package pe.gob.foncodes.ssa.web.controller;

import java.util.ArrayList;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import javax.faces.bean.ManagedBean;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.event.ValueChangeEvent; 
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import org.apache.log4j.Logger;
import org.primefaces.context.RequestContext;
import org.primefaces.event.NodeSelectEvent;
import org.primefaces.event.RowEditEvent;
import org.primefaces.event.SelectEvent;
import org.primefaces.model.DefaultTreeNode;
import org.primefaces.model.DualListModel;
import org.primefaces.model.TreeNode;
import pe.gob.foncodes.ssa.bs.administracion.controller.GenericMaintenanceController;
import pe.gob.foncodes.ssa.bs.common.util.Constante;
import pe.gob.foncodes.ssa.bs.seguridad.domain.UnidadOrganizacional;
import pe.gob.foncodes.ssa.bs.seguridad.domain.Usuario;
import pe.gob.foncodes.ssa.bs.seguridad.domain.Zonal;
import pe.gob.foncodes.ssa.bs.seguridad.service.UsuarioService;
import pe.gob.foncodes.ssa.bs.common.util.ServiceException;
import pe.gob.foncodes.ssa.bs.seguridad.domain.Accion;
import pe.gob.foncodes.ssa.bs.seguridad.domain.ControlAcceso;
import pe.gob.foncodes.ssa.bs.seguridad.domain.General;
import pe.gob.foncodes.ssa.bs.seguridad.domain.HorarioPerfil;
import pe.gob.foncodes.ssa.bs.seguridad.domain.Instancia;
import pe.gob.foncodes.ssa.bs.seguridad.domain.Modulo;
import pe.gob.foncodes.ssa.bs.seguridad.domain.Opcion;
import pe.gob.foncodes.ssa.bs.seguridad.domain.Perfil;
import pe.gob.foncodes.ssa.bs.seguridad.domain.PerfilOpcion;
import pe.gob.foncodes.ssa.bs.seguridad.domain.Personal;
import pe.gob.foncodes.ssa.bs.seguridad.domain.UsuarioAutorizacion;
import pe.gob.foncodes.ssa.bs.seguridad.domain.UsuarioAutorizacionPK;
import pe.gob.foncodes.ssa.bs.seguridad.domain.UsuarioInstancia;
import pe.gob.foncodes.ssa.bs.seguridad.domain.UsuarioInstanciaPK;
import pe.gob.foncodes.ssa.bs.seguridad.domain.UsuarioPerfil;
import pe.gob.foncodes.ssa.web.util.Utilitarios;

@ManagedBean(name = "usuarioController")
public class UsuarioController extends GenericMaintenanceController {

    protected static Logger log = Logger.getLogger(UsuarioController.class);
    private List<Usuario> lstUsuarios = new ArrayList<Usuario>();
    private List<General> lstTipoUsuario = new ArrayList<General>();
    private Usuario selectedUsuario = new Usuario();
    private String codUsuario;
    private String codUnidad;
    private String codZonal;
    private String mensaje;
    private boolean esNuevo;
    private boolean esNuevoExterno;
    private UsuarioService usuarioService;
    private List<Zonal> lstZonal;
    private Zonal selectedZonal;
    private String txtBusquedaUT;
    private List<UnidadOrganizacional> lstUnidadOrganizacional;
    private UnidadOrganizacional selectedUnidadOrganizacional;
    private String txtBusquedaUO;
    private String txtDNI;
    private String txtApenom;
    private List<Personal> lstPersonal;
    private Personal selectedPersonal;
    private Zonal selectedZonalUsuario;
    private boolean passwordExpira;
    private Date fechaExpiracion;
    private String txtNombreUsuarioSistema;
    private String txtPassword;
    private String txtCorreo1;
    private String txtCorreo2;
    
    private List<Zonal> lstComboZonal;
    private Map<String, String> mapaUnidadTerritorial = new HashMap<String, String>();
    private Map<String, String> mapaTipoUsuario = new HashMap<String, String>();
    private List<UnidadOrganizacional> lstComboUnidadOrganizacional;
    
    private boolean BMuestraObs;
    private boolean BActivo;
    private boolean BBloqueado;
    private boolean BCaducidadClave;
    
    private boolean BMuestraClave;
    
    public List<UsuarioPerfil> lstUsuarioPerfil = new ArrayList<UsuarioPerfil>();
    public UsuarioPerfil selectedUsuarioPerfil;
    
    public PerfilOpcion selectedUsuarioOpcion;
    
    public List<UsuarioAutorizacion> lstUsuarioAccion = new ArrayList<UsuarioAutorizacion>();
    public UsuarioAutorizacion selectedUsuarioAccion;
    
    private TreeNode moduloTree;
    private TreeNode selectedModuloNode;
    private Modulo selectedModuloPerfil;
    
    private TreeNode opcionTree;
    private TreeNode selectedOpcionNode;
    private PerfilOpcion selectedPerfilOpcion;
    
    private Long NIdPerfilSeleccionado;
    
    private DualListModel<Perfil> perfiles;
    private Map<String, Perfil> mapaPefiles = new HashMap<String, Perfil>();
    
    private DualListModel<Opcion> opciones;
    private Map<String, Opcion> mapaOpciones = new HashMap<String, Opcion>();
    
    private DualListModel<Instancia> instancias;
    private Map<String, Instancia> mapaInstancias = new HashMap<String, Instancia>();
    
    private List<Opcion> listaOpcionesAutorizadas = new ArrayList<Opcion>();
    
    public UsuarioPerfil selectedPersonalizaPerfil;
    private boolean BMuestraObsPerfil;
    private boolean BActivoPerfil;
    private boolean BTipoAcceso;
    private boolean BHorarioPerfil;
   
    public List<UsuarioAutorizacion> lstUsuarioAutorizacion = new ArrayList<UsuarioAutorizacion>();
    public UsuarioAutorizacion selectedUsuarioAutorizacion;
    private boolean BActivoAccion;
    private boolean BTipoAccesoAccion;
    
    //HorarioPerfil
    public List<HorarioPerfil> lstUsuarioHorarioPerfil = new ArrayList<HorarioPerfil>();
    private HorarioPerfil selectedHorarioPerfil = new HorarioPerfil();
    private boolean BActivoHorarioPerfil;
    private boolean BMuestraObsHorarioPerfil;
    
    private String tituloPanelOpciones;
    private String tituloPanelAcciones;
    
    private TreeNode visualizaTree;
    
    @Override
    public void init() throws Exception {
        selectedUsuario = null;
        selectedUnidadOrganizacional = null;
        selectedZonal = null;
        esNuevo = false;
        lstUsuarios = new ArrayList<Usuario>();
        setBeanList(lstUsuarios);
        lstZonal = new ArrayList<Zonal>();
        lstUnidadOrganizacional = new ArrayList<UnidadOrganizacional>();
        lstPersonal = new ArrayList<Personal>();
        lstTipoUsuario = getService().findByNamedQuery("General.findByTxtDominio", new Object[]{Constante.DOMINIO_TIPO_USUARIO});
        mapaTipoUsuario = new HashMap<String, String>();
        for (General general : lstTipoUsuario) {
            mapaTipoUsuario.put(general.getTxtValor(), general.getTxtParametro());
        }
        lstComboZonal = getService().findByNamedQuery("Zonal.findAll");
        mapaUnidadTerritorial = new HashMap<String, String>();
        for (Zonal zonal : lstComboZonal) {
            mapaUnidadTerritorial.put(zonal.getCodZonal().trim(), zonal.getTxtZonal());
        }
        List<Perfil> source = new ArrayList<Perfil>();  
        List<Perfil> target = new ArrayList<Perfil>();
        perfiles = new DualListModel<Perfil>(source, target);
        
        List<Opcion> sourceOpcion = new ArrayList<Opcion>();  
        List<Opcion> targetOpcion = new ArrayList<Opcion>();
        opciones = new DualListModel<Opcion>(sourceOpcion, targetOpcion);
        selectedPersonalizaPerfil = null;
        opcionTree = new DefaultTreeNode("root", null);
    }

    public void nuevo() {
        RequestContext context = RequestContext.getCurrentInstance();
        esNuevo = true;
        esNuevoExterno = false;
        BActivo = true;
        BBloqueado = false;
        setBean(new Usuario());
        context.execute("editarContenidoUsuarios.show()");
    }

    public void nuevoExterno() {
        RequestContext context = RequestContext.getCurrentInstance();
        esNuevo = true;
        esNuevoExterno = true;
        BActivo = true;
        BBloqueado = false;
        Usuario usuario = new Usuario();
        usuario.setTipUsuario(Constante.USUARIO_TIPO_EXTERNO);
        setBean(usuario);
        context.execute("editarContenidoUsuarios.show()");
    }
    
    public void searchUsuario() throws Exception {
        if (this.codUsuario == null) {
            this.codUsuario = "";
        }
        lstUsuarios = getUsuarioService().getUsuarioByUnidadTerritorialZonalUsuario(selectedZonal==null?null:selectedZonal.getCodZonal(),selectedUnidadOrganizacional==null?null:selectedUnidadOrganizacional.getCodUnidad(), this.codUsuario);
        setBeanList(lstUsuarios);
        selectedUsuario = null;
    }

    @Override
    public void clean(ActionEvent event) throws Exception {
        this.codUsuario = "";
        lstUsuarios = new ArrayList<Usuario>();
        setBeanList(lstUsuarios);
        if (selectedZonal !=null){
            selectedZonal = null;
        }
        if (selectedUnidadOrganizacional !=null){
            selectedUnidadOrganizacional = null;
        }
        if (selectedUsuario !=null){
            selectedUsuario = null;
        }
        if (selectedPersonal!=null){
            selectedPersonal=null;
        }
    }

    public void verDetallesUsuario() throws Exception{
        RequestContext context = RequestContext.getCurrentInstance();
        if (this.selectedUsuario == null) {
            setMessageError(new Exception("Debe seleccionar un registro"));
        } else {
            esNuevo = false;
            Usuario usuario = (Usuario) getService().findById(Usuario.class, selectedUsuario.getId());
            selectedUsuario = usuario;
            if (selectedUsuario.getFlgActivo().equals(Constante.ESTADO_ACTIVO)) {
                BActivo = true;
            } else {
                BActivo = false;
            }
            if (selectedUsuario.getFlgBloqueado().equals(Constante.ESTADO_ACTIVO)) {
                BBloqueado = true;
            } else {
                BBloqueado = false;
            }
            if (selectedUsuario.getFlgCaducidadClave().equals(Constante.ESTADO_ACTIVO)) {
                BCaducidadClave = true;
            }else{
                BCaducidadClave = false;
            }
            if (BActivo) {
                BMuestraObs = false;
            } else {
                BMuestraObs = true;
            }
            selectedZonalUsuario = (Zonal) getService().findById(Zonal.class, selectedUsuario.getCodZonal());
            setBean(this.selectedUsuario);
            context.execute("editarContenidoUsuarios.show()");
        }
    }
    
    public void saveDetalleUsuario(ActionEvent event) throws Exception {
        RequestContext context = RequestContext.getCurrentInstance();
        Usuario usuario = (Usuario) getBean();
        ControlAcceso control = ((ControlAcceso) getSpringBean(Constante.SESSION_ACCESO));
        usuario.setFlgActivo((BActivo)?Constante.ESTADO_ACTIVO:Constante.ESTADO_INACTIVO);
        usuario.setFlgCaducidadClave((BCaducidadClave)?Constante.ESTADO_ACTIVO:Constante.ESTADO_INACTIVO);
        usuario.setNIdCtrlAccesoWeb(control.getId());
        try {
            //Nuevo
            if (esNuevo) {
                if (validate()) {
                    usuario.setFlgBloqueado((BBloqueado)?Constante.ESTADO_ACTIVO:Constante.ESTADO_INACTIVO);
                    String strcomentario ="";
                    usuario.setTxtNombres(usuario.getTxtNombres().toUpperCase());
                    usuario.setTxtApellidoPaterno(usuario.getTxtApellidoPaterno().toUpperCase());
                    usuario.setTxtApellidoMaterno(usuario.getTxtApellidoMaterno().toUpperCase());
                    usuario.setTxtCorreoElectronico1(usuario.getTxtCorreoElectronico1().toLowerCase());
                    usuario.setTxtCorreoElectronico2(usuario.getTxtCorreoElectronico2().toLowerCase());
                    usuario.setCodUsuario(usuario.getCodUsuario().toUpperCase().trim());
                    usuario.setFecRegistro(Constante.FECHA_ACTUAL);
                    String firsLetterApeMat = usuario.getTxtApellidoMaterno().charAt(0)+"";
                    String firsLetterApePat = usuario.getTxtApellidoPaterno().charAt(0)+"";
                    String firsLetterNombre = usuario.getTxtNombres().charAt(0)+"";
                    int numAleatorio = (int) (Math.random() * (999 - 100 + 1) + 100);
                    if(!usuario.getTipUsuario().equals(Constante.USUARIO_TIPO_INTERNO)){
                        usuario.setTxtClave(retornaPasswordTemporal(usuario.getCodUsuario(),firsLetterApeMat,firsLetterApePat,firsLetterNombre, "1", numAleatorio));
                        strcomentario = "<span>Se remite el  c&oacute;digo de usuario  y su contrase&ntilde;a temporal. </span><br/>"
                                + "<span>La  primera vez que ingrese con esta cuenta, el sistema le pedir&aacute; de manera obligatoria el cambio de la contrase&ntilde;a temporal a su nueva clave.</span><br/><br/>"
                                + "<span>C&oacute;digo de Usuario: " + usuario.getCodUsuario() + "</span><br/>"
                                + "<span>Contrase&ntilde;a Temporal: " + retornaPasswordTemporal(usuario.getCodUsuario(),firsLetterApeMat,firsLetterApePat,firsLetterNombre, "0", numAleatorio) + "</span><br/><br/>";
                        if (usuario.getTxtCorreoElectronico1() != null) {
                            strcomentario += "<span>Correo Principal: " + usuario.getTxtCorreoElectronico1() + "</span><br/>";
                        }
                        if (usuario.getTxtCorreoElectronico2() != null) {
                            strcomentario += "<span>Correo Alternativo: " + usuario.getTxtCorreoElectronico2() + "</span><br/>";
                        }
                        strcomentario += "<br/><span>Se solicita verificar los datos, si hubiera alg&uacute;n error comunicar a el &aacute;rea correspondiente.</span><br/>";
                        strcomentario += "<br/><br/><span>Nota:  Este es un mensaje informativo enviado de forma autom&aacute;tica.</span><br/>";
                        strcomentario += "<span>Agradecemos no responder a esta direcci&oacute;n de correo</span><br/>";
                        usuario.setFlgCambioClave(Constante.ESTADO_ACTIVO);
                    }else{
                        strcomentario = "<span>Se remite el  c&oacute;digo de usuario interno. </span><br/>"
                                + "<span>Su contrase&ntilde;a de acceso es la misma que su contrase&ntilde;a de red. </span><br/><br/>"
                                + "<span>C&oacute;digo de Usuario: " + usuario.getCodUsuario() + "</span><br/><br/>";
                        if (usuario.getTxtCorreoElectronico1() != null) {
                            strcomentario += "<span>Correo Principal: " + usuario.getTxtCorreoElectronico1() + "</span><br/>";
                        }
                        if (usuario.getTxtCorreoElectronico2() != null) {
                            strcomentario += "<span>Correo Alternativo: " + usuario.getTxtCorreoElectronico2() + "</span><br/>";
                        }
                        strcomentario += "<br/><span>Se solicita verificar los datos, si hubiera alg&uacute;n error comunicar a el &aacute;rea correspondiente.</span><br/>";
                        strcomentario += "<br/><br/><span>Nota:  Este es un mensaje informativo enviado de forma autom&aacute;tica.</span><br/>";
                        strcomentario += "<span>Agradecemos no responder a esta direcci&oacute;n de correo</span><br/>";
                        usuario.setFlgCambioClave(Constante.ESTADO_INACTIVO);
                        usuario.setTxtClave(" ");
                    }
                    
                    usuario.setFlgAutomatico(Constante.FLAG_AUTOMATICO);
                    setBean(usuario);
                    super.beforeSave(event);
                    super.doSave(event);
                    afterSave(event);
                    if (usuario.getTxtCorreoElectronico1() != null) {
                        enviaMail(usuario.getTxtCorreoElectronico1(), "1", strcomentario);
                    }
                    if (usuario.getTxtCorreoElectronico2() != null) {
                        enviaMail(usuario.getTxtCorreoElectronico2(), "1", strcomentario);
                    }
                    context.execute("editarContenidoUsuarios.hide()");
                }
                //Modificar
            } else {
                if (validate()) {
                    usuario.setTxtNombres(usuario.getTxtNombres().toUpperCase());
                    usuario.setTxtApellidoPaterno(usuario.getTxtApellidoPaterno().toUpperCase());
                    usuario.setTxtApellidoMaterno(usuario.getTxtApellidoMaterno().toUpperCase());
                    usuario.setFlgBloqueado((BBloqueado)?Constante.ESTADO_ACTIVO:Constante.ESTADO_INACTIVO);
                    if(usuario.getFlgBloqueado().equals(Constante.ESTADO_INACTIVO)){
                        usuario.setTxtMotivoBloqueo(usuario.getTxtObservacion());
                        usuario.setFecBloqueo(null);
                    }
                    if(usuario.getFlgActivo().equals(Constante.ESTADO_ACTIVO) && !esNuevo) {
                        usuario.setTxtObservacion(null);
                    }
                    setBean(usuario);
                    super.beforeUpdate(event);
                    super.doUpdate(event);
                    afterUpdate(event);
                    context.execute("editarContenidoUsuarios.hide()");
                }
            }
        } catch (Exception e) {
            log.error(e);
        }
    }

    @Override
    public void afterSave(ActionEvent event) throws Exception {
        esNuevo = false;
        setMessageSuccess("Se creo el usuario " + "'" + ((Usuario) getBean()).getNombreCompleto() + "'" + " satisfactoriamente.");
        log.info("End of Transaction: 'Save'");
    }
    
    @Override
    public void afterUpdate(ActionEvent event) throws Exception {
        setMessageSuccess("Se actualizó el usuario " + "'" + ((Usuario) getBean()).getNombreCompleto() + "'" + " satisfactoriamente.");
        log.info("End of Transaction: 'Update'");
    }
    
    @Override
    public boolean validate() throws Exception {
        boolean success = true;
        Usuario usuario = (Usuario)getBean();
        if(usuario.getTipUsuario() == null){
            setMessageError(new Exception("Se debe seleccionar el Tipo de Usuario."));
            success = false;
            return success;
        }
        if(usuario.getTipUsuario().equals(Constante.NO_OPTION_SELECTED)){
            setMessageError(new Exception("Se debe seleccionar el Tipo de Usuario."));
            success = false;
            return success;
        }
        if (usuario.getCodDni() == null ){
            usuario.setCodDni("");
        }
        if(usuario.getCodDni().trim().equals("")) {
            setMessageError(new Exception("Se debe ingresar el DNI."));
            success = false;
            return success;
        }
        if (usuario.getCodUsuario() == null ){
            usuario.setCodUsuario("");
        }
        if(usuario.getCodUsuario().trim().equals("")) {
            setMessageError(new Exception("Se debe ingresar el código de usuario."));
            success = false;
            return success;
        }
        if(usuario.getTipUsuario().equals(Constante.USUARIO_TIPO_INTERNO)){
            if(usuario.getCodUsuario().lastIndexOf(Constante.CARACTER_USUARIO_DOMINIO) > -1){
                setMessageError(new Exception("El código de usuario no debe presentar el caracter '"+Constante.CARACTER_USUARIO_DOMINIO+"'."));
                success = false;
                return success;
            }
        }
        if (usuario.getTxtNombres() == null ){
            usuario.setTxtNombres("");
        }
        if(usuario.getTxtNombres().trim().equals("")) {
            setMessageError(new Exception("Se debe ingresar el nombre de usuario."));
            success = false;
            return success;
        }
        if (usuario.getTxtApellidoPaterno() == null ){
            usuario.setTxtApellidoPaterno("");
        }
        if(usuario.getTxtApellidoPaterno().trim().equals("")) {
            setMessageError(new Exception("Se debe ingresar el apellido paterno del usuario."));
            success = false;
            return success;
        }
        if (usuario.getTxtApellidoMaterno() == null ){
            usuario.setTxtApellidoMaterno("");
        }
        if(usuario.getTxtApellidoMaterno().trim().equals("")) {
            setMessageError(new Exception("Se debe ingresar el apellido materno del usuario."));
            success = false;
            return success;
        }
        if(usuario.getCodZonal() == null){
            setMessageError(new Exception("Se debe ingresar la Unidad Territorial."));
            success = false;
            return success;
        }
        if(usuario.getTxtCorreoElectronico1() == null){
            usuario.setTxtCorreoElectronico1("");
        }
        if(usuario.getTxtCorreoElectronico1().trim().equals("")){
            setMessageError(new Exception("Se debe ingresar el Correo Electronico 1."));
            success = false;
            return success;
        }
        if(usuario.getTxtCorreoElectronico2() == null){
            usuario.setTxtCorreoElectronico2("");
        }
        if(usuario.getTipUsuario().equals(Constante.USUARIO_TIPO_EXTERNO)){
            if(usuario.getFecCambioClave() == null){
                setMessageError(new Exception("Se debe ingresar la fecha de expiración de la contraseña."));
                success = false;
                return success;
            }
        }
        if(BCaducidadClave){
            if(usuario.getFecCambioClave() == null){
                setMessageError(new Exception("Se debe ingresar la fecha de expiración de la contraseña."));
                success = false;
                return success;
            }
        }
        if (!usuario.getCodUsuario().equals("")) {
            List listaUsuarioRep = getService().findByObjectDif("Usuario", "codUsuario", usuario.getCodUsuario().trim().toUpperCase(), usuario.getId());
            if (listaUsuarioRep != null && !listaUsuarioRep.isEmpty()) {
                setMessageError(new Exception("Ya existe un usuario registrado con el mismo código de usuario."));
                success = false;
                return success;
            }
        }
        if(!esNuevo){
            if(usuario.getFlgBloqueado().equals(Constante.ESTADO_ACTIVO)){
                if (usuario.getTxtObservacion() == null) {
                    usuario.setTxtObservacion("");
                }
                if (usuario.getTxtObservacion().equals("") && !BBloqueado) {
                    setMessageError(new Exception("Se debe ingresar la observación."));
                    success = false;
                    return success;
                }
            }
            
        }
        if(usuario.getFlgActivo().equals(Constante.ESTADO_INACTIVO)) {
            if (usuario.getTxtObservacion() == null ){
                usuario.setTxtObservacion("");
            }
            if(usuario.getTxtObservacion().equals("")){
                setMessageError(new Exception("Se debe ingresar la observación."));
                success = false;
                return success;
            }
        }
        return success;
    }

    public void validaReinicioPassword() {
        RequestContext context = RequestContext.getCurrentInstance();
        if (this.selectedUsuario == null) {
            FacesContext faces = FacesContext.getCurrentInstance();
            faces.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error", "Debe seleccionar un registro"));
        } else {
            if (this.selectedUsuario.getFlgActivo().equals(Constante.ESTADO_INACTIVO)) {
                setMessageError(new Exception("El usuario se encuentra desactivado"));
            }else{
                if(this.selectedUsuario.getTipUsuario().equals(Constante.USUARIO_TIPO_INTERNO)){
                    setMessageError(new Exception("El usuario es de tipo INTERNO"));    
                }else{
                    context.execute("msjReiniciarContra.show()");
                }
            }
        }
    }

    public void reiniciarPassword() throws Exception{
        RequestContext context = RequestContext.getCurrentInstance();
        ControlAcceso control = ((ControlAcceso) getSpringBean(Constante.SESSION_ACCESO));
        int numAleatorio = (int)(Math.random()*(999-100+1)+100);
        String firsLetterApeMat = selectedUsuario.getTxtApellidoMaterno().charAt(0)+"";
        String firsLetterApePat = selectedUsuario.getTxtApellidoPaterno().charAt(0)+"";
        String firsLetterNombre = selectedUsuario.getTxtNombres().charAt(0)+"";
        String strcomentario = "<span>Se remite el  c&oacute;digo de usuario  y su contrase&ntilde;a temporal.</span><br/>"
                        + "<span>La  primera vez que ingrese con esta cuenta, el sistema le pedir&aacute; de manera obligatoria el cambio de la contrase&ntilde;a temporal a su nueva clave.</span><br/><br/>"
                        + "<span>C&oacute;digo de Usuario: " + selectedUsuario.getCodUsuario()+"</span><br/>"
                        + "<span>Contrase&ntilde;a Temporal: " + retornaPasswordTemporal(selectedUsuario.getCodUsuario(),firsLetterApeMat,firsLetterApePat,firsLetterNombre,"0",numAleatorio)+"</span><br/><br/>";
        if (selectedUsuario.getTxtCorreoElectronico1() != null) {
            strcomentario += "<span>Correo Principal: " + selectedUsuario.getTxtCorreoElectronico1() + "</span><br/>";
        }
        if (selectedUsuario.getTxtCorreoElectronico2() != null) {
            strcomentario += "<span>Correo Alternativo: " + selectedUsuario.getTxtCorreoElectronico2() + "</span><br/>";
        }
        strcomentario += "<br/><span>Se solicita verificar los datos, si hubiera alg&uacute;n error comunicar a el &aacute;rea correspondiente.</span><br/>";
        strcomentario += "<br/><br/><span>Nota:  Este es un mensaje informativo enviado de forma autom&aacute;tica.</span><br/>";
        strcomentario += "<span>Agradecemos no responder a esta direcci&oacute;n de correo</span><br/>";
        
        selectedUsuario.setFlgCambioClave(Constante.ESTADO_ACTIVO);
        selectedUsuario.setTxtClave(retornaPasswordTemporal(selectedUsuario.getCodUsuario(),firsLetterApeMat,firsLetterApePat,firsLetterNombre,"1",numAleatorio));
        selectedUsuario.setNIdCtrlAccesoWeb(control.getId());
        
        setBean(selectedUsuario);
        super.beforeUpdate(null);
        super.doUpdate(null);
        log.info("End of Transaction: 'Update'");
        //getService().save(selectedUsuario);
        mensaje = "Se reinicio la contraseña del usuario "+ selectedUsuario.getTxtApellidoPaterno() + " " + selectedUsuario.getTxtApellidoMaterno() + " " + selectedUsuario.getTxtNombres()+" "
                + "satisfactoriamente y se la ha generado una contraseña temporal, "
                + "la cual ha sido enviada a el(los) correo(s) registrado(s) en nuestra base de datos";
        context.execute("msjReiniciarContra.hide()");
        context.execute("msjConfimaReinicioOK.show()");
        if (selectedUsuario.getTxtCorreoElectronico1() != null) {
            enviaMail(selectedUsuario.getTxtCorreoElectronico1(), "1", strcomentario);
        }
        if (selectedUsuario.getTxtCorreoElectronico2() != null) {
            enviaMail(selectedUsuario.getTxtCorreoElectronico2(), "1", strcomentario);
        }
    }
    
    public void validarAsignarPermisos() {
        RequestContext context = RequestContext.getCurrentInstance();
        if (this.selectedUsuario == null) {
            setMessageError(new Exception("Debe seleccionar un registro"));
        } else {
            if (this.selectedUsuario.getFlgActivo().equals(Constante.ESTADO_INACTIVO)) {
                setMessageError(new Exception("El usuario se encuentra desactivado"));
            }else{
                setBean(selectedUsuario);
                lstUsuarioPerfil = new ArrayList<UsuarioPerfil>();
                tituloPanelOpciones = "Opciones Asignadas";
                tituloPanelAcciones = "Acciones Asignadas";
                selectedUsuarioPerfil = null;
                selectedUsuarioOpcion = null;
                moduloTree = new DefaultTreeNode("root", null);
                opcionTree = new DefaultTreeNode("root", null);
                selectedOpcionNode = null;
                try {
                    lstUsuarioPerfil = getService().findByNamedQuery("UsuarioPerfil.findByNidUsuario", new Object[]{selectedUsuario.getId()});
                    selectedModuloNode = null;
                    selectedModuloPerfil = null;
                    lstUsuarioAccion = new ArrayList<UsuarioAutorizacion>();
                    selectedUsuarioAccion = null;
                    List<Modulo> lstModuloInicial = getService().findByNamedQuery("Modulo.findOnlyNidModuloPadreAndFlgActivo", new Object[]{Constante.ESTADO_ACTIVO});
                    for (Modulo modulo : lstModuloInicial) {
                        TreeNode padre = new DefaultTreeNode(modulo, moduloTree);
                    }
                } catch (ServiceException ex) {
                    log.error("ERROR EN validarAsignarPermisos = "+ex.getMessage());
                }
                context.execute("asignaPermisos.show()");
            }
        }
    }
    
    /**
     * Cambio de metodo
     * @param event 
     */
    public void listaOpcionesDePerfil(SelectEvent event){
        selectedUsuarioPerfil = (UsuarioPerfil) event.getObject();
        if(selectedUsuarioPerfil != null){
            tituloPanelOpciones = "Opciones Asignadas del Perfil "+selectedUsuarioPerfil.getNidPerfil().getTxtPerfil();
            listaOpcionesDePerfilSinEvento();
        }
    }
    
    public void listaOpcionesDePerfilSinEvento(){
        if (this.selectedUsuarioPerfil.getFlgActivo().equals(Constante.ESTADO_INACTIVO)) {
            opcionTree = new DefaultTreeNode("root", null);
            selectedUsuarioOpcion = null;
            lstUsuarioAccion = new ArrayList<UsuarioAutorizacion>();
            selectedUsuarioAccion = null;
        } else {
            try {
                opcionTree = new DefaultTreeNode("root", null);
                Modulo moduloPadre = null;
                if (selectedUsuarioPerfil.getNidPerfil().getNidModulo().getNidModuloPadre() == null) {
                    moduloPadre = selectedUsuarioPerfil.getNidPerfil().getNidModulo();
                } else {
                    moduloPadre = getUsuarioService().getModuloPadre(selectedUsuarioPerfil.getNidPerfil().getNidModulo().getId());
                }
                TreeNode treePadre = new DefaultTreeNode(moduloPadre, opcionTree);
                treePadre.setExpanded(true);
                loadPadreTreeVisualiza(treePadre,moduloPadre);
                /*
                List<Object[]> lstObject = getService().findByNamedQuery("UsuarioAutorizacion.findByUsuarioPerfilFirstLevelNodes", new Object[]{selectedUsuarioPerfil.getId(), Constante.ESTADO_ACTIVO, Constante.ESTADO_ACTIVO, selectedUsuarioPerfil.getNidPerfil().getId()});
                List<PerfilOpcion> lstOpcionPadre = new ArrayList<PerfilOpcion>();
                PerfilOpcion po = null;
                for (Object[] obj : lstObject) {
                    po = new PerfilOpcion();
                    po.setOpcion((Opcion)obj[0]);
                    po.setPerfil(selectedUsuarioPerfil.getNidPerfil());
                    po.setFlgConsulta(obj[1].toString());
                    lstOpcionPadre.add(po);
                }
                for (PerfilOpcion perfilOpcion : lstOpcionPadre) {
                    TreeNode padre = new DefaultTreeNode(perfilOpcion, opcionTree);
                    padre.setExpanded(true);
                    loadHijoTree(padre, perfilOpcion, selectedUsuarioPerfil);
                }
                */
                selectedUsuarioOpcion = null;
                lstUsuarioAccion = new ArrayList<UsuarioAutorizacion>();
                selectedUsuarioAccion = null;
            } catch (ServiceException ex) {
                log.error("ERROR EN listaOpcionesDePerfilSinEvento = "+ex.getMessage());
            }
        }
    }
    
    public void loadHijoTree(TreeNode hijo, PerfilOpcion opHijo, UsuarioPerfil selectedUsuarioPerfil) throws ServiceException {
        List<Object[]> lstObject = getService().findByNamedQuery("UsuarioAutorizacion.findByUsuarioPerfilOtherLevelNodes", new Object[]{selectedUsuarioPerfil.getId(), Constante.ESTADO_ACTIVO, Constante.ESTADO_ACTIVO, selectedUsuarioPerfil.getNidPerfil().getId(), opHijo.getOpcion().getId()});
        List<PerfilOpcion> lstOpcionHijos = new ArrayList<PerfilOpcion>();
        PerfilOpcion po = null;
        for (Object[] obj : lstObject) {
            po = new PerfilOpcion();
            po.setOpcion((Opcion) obj[0]);
            po.setPerfil(selectedUsuarioPerfil.getNidPerfil());
            po.setFlgConsulta(obj[1].toString());
            lstOpcionHijos.add(po);
        }
        for (PerfilOpcion perfilOpcion : lstOpcionHijos) {
            TreeNode nieto = new DefaultTreeNode(perfilOpcion, hijo);
            nieto.setExpanded(true);
            loadHijoTree(nieto, perfilOpcion, selectedUsuarioPerfil);
        }
    }
    
    public void listaAccionesDeOpcionDelPerfil(NodeSelectEvent event) {
        //validar si es perfil opcion
        if(event.getTreeNode().getType().equals("document")){
            selectedUsuarioOpcion = (PerfilOpcion) event.getTreeNode().getData();
            if(selectedUsuarioOpcion != null){
                tituloPanelAcciones = "Acciones Asignadas de la Opción "+selectedUsuarioOpcion.getOpcion().getTxtOpcion();
                listaAccionesDeOpcionDelPerfilSinEvento(selectedUsuarioOpcion);
            }
        }else{
            selectedUsuarioAccion = null;
            lstUsuarioAccion = new ArrayList<UsuarioAutorizacion>();
        }
    }
    
    public void limpiaAccionesDeOpcionDelPerfil(){
        selectedOpcionNode = null;
        selectedUsuarioOpcion = null;
        lstUsuarioAccion = new ArrayList<UsuarioAutorizacion>();
        selectedUsuarioAccion = null;
        log.info("selectedOpcionNode="+selectedOpcionNode);
        log.info("selectedUsuarioOpcion="+selectedUsuarioOpcion);
    }
    
    public void listaAccionesDeOpcionDelPerfilSinEvento(PerfilOpcion selectedPerfilOpcion){
        selectedUsuarioAccion = null;
        lstUsuarioAccion = new ArrayList<UsuarioAutorizacion>();
        if(selectedPerfilOpcion != null){
           try {
                selectedUsuarioOpcion = selectedPerfilOpcion;
                lstUsuarioAccion =  getService().findByNamedQuery("UsuarioAutorizacion.findByNidAccionAndNidUsuarioPerfil", new Object[]{ selectedUsuarioOpcion.getOpcion().getId(), selectedUsuarioPerfil.getId(), Constante.ESTADO_ACTIVO});
            } catch (ServiceException ex) {
                log.error("ERROR EN listaAccionesDeOpcionDelPerfilSinEvento = "+ex.getMessage());
            } 
        }
    }
    
    public String retornaPasswordTemporal(String codUsuario, String firsLetterApeMat, String firsLetterApePat, String firsLetterNombre, String tipo, Integer numAleatorio) throws ServiceException {
        String codUsuarioSinArroba = codUsuario;
        if(codUsuarioSinArroba.lastIndexOf(Constante.CARACTER_USUARIO_DOMINIO) > -1){
            codUsuarioSinArroba = codUsuarioSinArroba.replace(Constante.CARACTER_USUARIO_DOMINIO+"", "");
        }
        String enc_clave = codUsuarioSinArroba + firsLetterApeMat + firsLetterApePat + firsLetterNombre + numAleatorio;
        log.info("Clave DesEncriptada: " + enc_clave);
        if(tipo.equals("1")){
            enc_clave = getUsuarioService().retornaClaveEncriptada(enc_clave, codUsuario);
            log.info("Clave Encriptada: " + enc_clave);
        }
        return enc_clave;
    }
    
    public String getCodUnidad() {
        return codUnidad;
    }

    public void setCodUnidad(String codUnidad) {
        this.codUnidad = codUnidad;
    }

    public String getCodUsuario() {
        return codUsuario;
    }

    public void setCodUsuario(String codUsuario) {
        this.codUsuario = codUsuario;
    }

    public String getCodZonal() {
        return codZonal;
    }

    public void setCodZonal(String codZonal) {
        this.codZonal = codZonal;
    }

    public boolean isEsNuevo() {
        return esNuevo;
    }

    public void setEsNuevo(boolean esNuevo) {
        this.esNuevo = esNuevo;
    }

    public List<Usuario> getLstUsuarios() {
        return lstUsuarios;
    }

    public void setLstUsuarios(List<Usuario> lstUsuarios) {
        this.lstUsuarios = lstUsuarios;
    }

    public String getMensaje() {
        return mensaje;
    }

    public void setMensaje(String mensaje) {
        this.mensaje = mensaje;
    }

    public Usuario getSelectedUsuario() {
        return selectedUsuario;
    }

    public void setSelectedUsuario(Usuario selectedUsuario) {
        this.selectedUsuario = selectedUsuario;
    }

    public UsuarioService getUsuarioService() {
        return usuarioService;
    }

    public void setUsuarioService(UsuarioService usuarioService) {
        this.usuarioService = usuarioService;
    }

    /**
     * @return the lstZonal
     */
    public List<Zonal> getLstZonal() {
        return lstZonal;
    }

    /**
     * @param lstZonal the lstZonal to set
     */
    public void setLstZonal(List<Zonal> lstZonal) {
        this.lstZonal = lstZonal;
    }

    /**
     * @return the txtBusqueda
     */
    public String getTxtBusquedaUT() {
        return txtBusquedaUT;
    }

    /**
     * @param txtBusqueda the txtBusqueda to set
     */
    public void setTxtBusquedaUT(String txtBusquedaUT) {
        this.txtBusquedaUT = txtBusquedaUT;
    }

    /**
     * @return the selectedZonal
     */
    public Zonal getSelectedZonal() {
        return selectedZonal;
    }

    /**
     * @param selectedZonal the selectedZonal to set
     */
    public void setSelectedZonal(Zonal selectedZonal) {
        this.selectedZonal = selectedZonal;
    }

    public void searchUnidadTerritorial() throws Exception {
        if (this.txtBusquedaUT == null) {
            this.txtBusquedaUT = "";
        }
        lstZonal = getService().findByNamedQuery("Zonal.findByTxtZonal", new Object[]{this.txtBusquedaUT.toUpperCase() + "%"});
        selectedZonal = null;
    }

    public void limpiarBusquedaUnidadTerritorial() throws Exception {
        this.txtBusquedaUT = "";
        lstZonal = new ArrayList<Zonal>();
    }

    public void actualizarUTSeleccion(Zonal utseleccionado) throws Exception {
        this.selectedZonal = utseleccionado;
        if (this.selectedZonal == null) {
            log.info("El UT seleccionado es null");
        }
    }
    
    public void actualizarUTUsuarioSeleccion(Zonal utseleccionado) throws Exception {
        this.selectedZonalUsuario = utseleccionado;
        if (this.selectedZonalUsuario == null) {
            log.info("El UT seleccionado es null");
        }else{
            Usuario userSeleccionado = (Usuario) getBean();
            userSeleccionado.setCodZonal(this.selectedZonalUsuario.getCodZonal());
            setBean(userSeleccionado);
        }
    }
    /**
     * @return the lstUnidadOrganizacional
     */
    public List<UnidadOrganizacional> getLstUnidadOrganizacional() {
        return lstUnidadOrganizacional;
    }

    /**
     * @param lstUnidadOrganizacional the lstUnidadOrganizacional to set
     */
    public void setLstUnidadOrganizacional(List<UnidadOrganizacional> lstUnidadOrganizacional) {
        this.lstUnidadOrganizacional = lstUnidadOrganizacional;
    }

    /**
     * @return the selectedUnidadOrganizacional
     */
    public UnidadOrganizacional getSelectedUnidadOrganizacional() {
        return selectedUnidadOrganizacional;
    }

    /**
     * @param selectedUnidadOrganizacional the selectedUnidadOrganizacional to set
     */
    public void setSelectedUnidadOrganizacional(UnidadOrganizacional selectedUnidadOrganizacional) {
        this.selectedUnidadOrganizacional = selectedUnidadOrganizacional;
    }

    /**
     * @return the txtBusquedaUO
     */
    public String getTxtBusquedaUO() {
        return txtBusquedaUO;
    }

    /**
     * @param txtBusquedaUO the txtBusquedaUO to set
     */
    public void setTxtBusquedaUO(String txtBusquedaUO) {
        this.txtBusquedaUO = txtBusquedaUO;
    }

    public void limpiarBusquedaUnidadOrganizacional() throws Exception {
        this.txtBusquedaUO = "";
        lstUnidadOrganizacional = new ArrayList<UnidadOrganizacional>();
    }

    public void searchUnidadOrganizacional() throws Exception {
        if (this.txtBusquedaUO == null) {
            this.txtBusquedaUO = "";
        }
        lstUnidadOrganizacional = getService().findByNamedQuery("UnidadOrganizacional.findByTxtUO", new Object[]{this.txtBusquedaUO.toUpperCase() + "%"});
        selectedUnidadOrganizacional = null;
    }
    
    public void limpiarBusquedaPersonal() throws Exception {
        lstPersonal = new ArrayList<Personal>();
        Usuario usuario = (Usuario)getBean();
        this.txtDNI = usuario.getCodDni();
        this.txtApenom = "";
        if (this.txtDNI == null){
           this.txtDNI=""; 
        }
        if(!this.txtDNI.equals("")){
            searchPersonal();
        }
    }
    
    public void searchPersonal() throws Exception {
        if (this.txtDNI ==null){
           this.txtDNI="";
        }
        if (this.txtApenom ==null){
            this.txtApenom="";
        }
        if(this.txtDNI.equals("") && this.txtApenom.equals("")){
            setMessageError(new Exception("Debe ingresar al menos un filtro"));
            return;
        }else{
            if (this.txtDNI.equals("") && this.txtApenom.length()<3){
                setMessageError(new Exception("Debe ingresar al menos 3 caracteres para poder realizar la busqueda por apellidos y nombres"));
                return;
            }
        }
        Usuario usuario = (Usuario)getBean();
        usuario.setCodDni(txtDNI);
        setBean(usuario);
        if (!this.txtDNI.equals("") && this.txtApenom.equals("")){
            lstPersonal = getService().findByNamedQuery("Personal.findByDNI",new Object[]{(this.txtDNI.equals(""))?null:this.txtDNI});
        }else{
            if (this.txtDNI.equals("") && !this.txtApenom.equals("")){
                lstPersonal = getService().findByNamedQuery("Personal.findByApeNom",new Object[]{this.txtApenom.toUpperCase()+ "%"});
            }else{
                lstPersonal = getService().findByNamedQuery("Personal.findByDNIApeNom",new Object[]{(this.txtDNI.equals(""))?null:this.txtDNI,this.txtApenom.toUpperCase()+ "%"});
            }
        }
        selectedPersonal =null;
    }

    public void actualizarUOSeleccion(UnidadOrganizacional uoseleccionado) throws Exception {
        this.selectedUnidadOrganizacional = uoseleccionado;
        if (this.selectedUnidadOrganizacional == null) {
            log.info("El UO seleccionado es null");
        }
    }
    
    public void actualizarPersonalSeleccion(Personal personalseleccionado) throws Exception {
        this.selectedPersonal = personalseleccionado;
        
        if (this.selectedPersonal == null) {
            log.info("El Personal seleccionado es null");
        }else{
            Usuario userSeleccionado = (Usuario) getBean();
            userSeleccionado.setNidPersonal(selectedPersonal.getNidPersonal());
            userSeleccionado.setTxtApellidoPaterno(this.selectedPersonal.getTxtApellidoPaterno());
            userSeleccionado.setTxtApellidoMaterno(this.selectedPersonal.getTxtApellidoMaterno());
            userSeleccionado.setTxtNombres(this.selectedPersonal.getTxtNombres());
            userSeleccionado.setCodDni(this.selectedPersonal.getTxtDni());
            userSeleccionado.setCodUsuario(this.selectedPersonal.getTxtDni());
            if(selectedPersonal.getCodUnidad() != null){
                if(selectedPersonal.getCodUnidad().getCodZonal()!= null){
                    Zonal zonal = (Zonal) getService().findById(Zonal.class, selectedPersonal.getCodUnidad().getCodZonal());
                    if(zonal != null){
                        selectedZonalUsuario = zonal;
                        userSeleccionado.setCodZonal(zonal.getCodZonal());
                    }
                }
            }else{
                selectedZonalUsuario = null;
            }
            setBean(userSeleccionado);
            cambiaCodigoUsuarioPorTipoSinEvento();
        }
    }
    public List<General> getLstTipoUsuario() throws ServiceException {
        return lstTipoUsuario;
    }

    /**
     * @param lstTipoUsuario the lstTipoUsuario to set
     */
    public void setLstTipoUsuario(List<General> lstTipoUsuario) {
        this.lstTipoUsuario = lstTipoUsuario;
    }

    /**
     * @return the txtDNI
     */
    public String getTxtDNI() {
        return txtDNI;
    }

    /**
     * @param txtDNI the txtDNI to set
     */
    public void setTxtDNI(String txtDNI) {
        this.txtDNI = txtDNI;
    }

    /**
     * @return the txtApenom
     */
    public String getTxtApenom() {
        return txtApenom;
    }

    /**
     * @param txtApenom the txtApenom to set
     */
    public void setTxtApenom(String txtApenom) {
        this.txtApenom = txtApenom;
    }

    /**
     * @return the lstPersonal
     */
    public List<Personal> getLstPersonal() {
        return lstPersonal;
    }

    /**
     * @param lstPersonal the lstPersonal to set
     */
    public void setLstPersonal(List<Personal> lstPersonal) {
        this.lstPersonal = lstPersonal;
    }

    /**
     * @return the selectedPersonal
     */
    public Personal getSelectedPersonal() {
        return selectedPersonal;
    }

    /**
     * @param selectedPersonal the selectedPersonal to set
     */
    public void setSelectedPersonal(Personal selectedPersonal) {
        this.selectedPersonal = selectedPersonal;
    }

    /**
     * @return the selectedZonalUsuario
     */
    public Zonal getSelectedZonalUsuario() {
        return selectedZonalUsuario;
    }

    /**
     * @param selectedZonalUsuario the selectedZonalUsuario to set
     */
    public void setSelectedZonalUsuario(Zonal selectedZonalUsuario) {
        this.selectedZonalUsuario = selectedZonalUsuario;
    }

    /**
     * @return the passwordExpira
     */
    public boolean isPasswordExpira() {
        return passwordExpira;
    }

    /**
     * @param passwordExpira the passwordExpira to set
     */
    public void setPasswordExpira(boolean passwordExpira) {
        this.passwordExpira = passwordExpira;
    }

    /**
     * @return the fechaExpiracion
     */
    public Date getFechaExpiracion() {
        return fechaExpiracion;
    }

    /**
     * @param fechaExpiracion the fechaExpiracion to set
     */
    public void setFechaExpiracion(Date fechaExpiracion) {
        this.fechaExpiracion = fechaExpiracion;
    }

    /**
     * @return the txtNombreUsuarioSistema
     */
    public String getTxtNombreUsuarioSistema() {
        return txtNombreUsuarioSistema;
    }

    /**
     * @param txtNombreUsuarioSistema the txtNombreUsuarioSistema to set
     */
    public void setTxtNombreUsuarioSistema(String txtNombreUsuarioSistema) {
        this.txtNombreUsuarioSistema = txtNombreUsuarioSistema;
    }

    /**
     * @return the txtPassword
     */
    public String getTxtPassword() {
        return txtPassword;
    }

    /**
     * @param txtPassword the txtPassword to set
     */
    public void setTxtPassword(String txtPassword) {
        this.txtPassword = txtPassword;
    }

    /**
     * @return the txtCorreo1
     */
    public String getTxtCorreo1() {
        return txtCorreo1;
    }

    /**
     * @param txtCorreo1 the txtCorreo1 to set
     */
    public void setTxtCorreo1(String txtCorreo1) {
        this.txtCorreo1 = txtCorreo1;
    }

    /**
     * @return the txtCorreo2
     */
    public String getTxtCorreo2() {
        return txtCorreo2;
    }

    /**
     * @param txtCorreo2 the txtCorreo2 to set
     */
    public void setTxtCorreo2(String txtCorreo2) {
        this.txtCorreo2 = txtCorreo2;
    }

    public boolean isBActivo() {
        return BActivo;
    }

    public void setBActivo(boolean BActivo) {
        this.BActivo = BActivo;
    }

    public boolean isBBloqueado() {
        return BBloqueado;
    }

    public void setBBloqueado(boolean BBloqueado) {
        this.BBloqueado = BBloqueado;
    }

    public boolean isBMuestraObs() {
        return BMuestraObs;
    }

    public void setBMuestraObs(boolean BMuestraObs) {
        this.BMuestraObs = BMuestraObs;
    }
    
    public void muestraObservacion() {  
        BMuestraObs = (BBloqueado)?false:true;
        Usuario usuario = (Usuario)getBean();
        String observacion="";
        if(usuario.getTxtObservacion() != null){
            observacion = usuario.getTxtObservacion();
        }
        if(usuario.getTxtMotivoBloqueo()!= null){
            observacion = usuario.getTxtMotivoBloqueo()+ " " +observacion;
            usuario.setTxtObservacion(observacion);
        }
    }

    public void muestraObservacionActivo() {  
        BMuestraObs = (BActivo)?false:true;
    }
    
    public boolean isBCaducidadClave() {
        return BCaducidadClave;
    }

    public void setBCaducidadClave(boolean BCaducidadClave) {
        this.BCaducidadClave = BCaducidadClave;
    }

    public boolean isBMuestraClave() {
        return BMuestraClave;
    }

    public void setBMuestraClave(boolean BMuestraClave) {
        this.BMuestraClave = BMuestraClave;
    }
    
    public void cambiaCodigoUsuarioPorTipo(ValueChangeEvent event) {
        Object objNew = event.getNewValue();
        if (objNew != null) {
            Usuario usuario = (Usuario) getBean();
            usuario.setTipUsuario(objNew.toString());
            setBean(usuario);
            cambiaCodigoUsuarioPorTipoSinEvento();
        }
    }
    
    public void cambiaCodigoUsuarioPorTipoSinEvento(){
        Usuario usuario = (Usuario) getBean();
        if(usuario.getTipUsuario()!=null){
            if(usuario.getTipUsuario().equals(Constante.USUARIO_TIPO_INTERNO)){
                //la primera letra del primer nombre seguido del apellido paterno
                String sFirstLetter = (usuario.getTxtNombres()==null)?"":usuario.getTxtNombres().charAt(0)+"";
                String sApePat = (usuario.getTxtApellidoPaterno()==null)?"":usuario.getTxtApellidoPaterno();
                usuario.setCodUsuario(sFirstLetter.trim() + sApePat.trim());
                BMuestraClave = false;
                try {
                    General genDominioCorreo = (General) getService().findGeneralByCode(General.class, Constante.DOMINIO_CORREO_USUARIO_INTERNO);
                    if(genDominioCorreo != null){
                        usuario.setTxtCorreoElectronico1(usuario.getCodUsuario() + genDominioCorreo.getTxtValor());
                    }
                } catch (Exception ex) {
                    log.error("ERROR EN cambiaCodigoUsuarioPorTipoSinEvento: "+ex.getMessage());
                }
            }else{
                BMuestraClave = true;
                String sDni = (usuario.getCodDni()==null)?"":usuario.getCodDni();
                usuario.setCodUsuario(Constante.CARACTER_USUARIO_DOMINIO + sDni.trim());
                usuario.setTxtCorreoElectronico1("");
            }
            setBean(usuario);
        }
    }
    
    public void enviaMail(String strmailpara, String tipo, String strcomentario) {
        try {
            String strmail = Utilitarios.getContextUrl("1");
            String struser = Utilitarios.getContextUrl("2");
            String strpass = Utilitarios.getContextUrl("3");
            String strmailde = Utilitarios.getContextUrl("4");

            Properties props = new Properties();
            props.setProperty("mail.smtp.host", strmail);
            //props.setProperty("mail.smtp.starttls.enable", "true");
            props.setProperty("mail.smtp.port", "587");
            props.setProperty("mail.smtp.user", struser);
            props.setProperty("mail.smtp.auth", "false");

            // Preparamos la sesion
            Session session = Session.getDefaultInstance(props);

            // Construimos el mensaje
            MimeMessage message = new MimeMessage(session);
            message.setFrom(new InternetAddress(strmailde));
            message.addRecipient(
                    Message.RecipientType.TO,
                    new InternetAddress(strmailpara));
            if(tipo.equals("1")){
                message.setSubject("Notificación del sistema de seguridad de FONCODES - Contraseña Temporal");
            }else if(tipo.equals("2")){
                message.setSubject("Notificación del sistema de seguridad de FONCODES - Cambio de Contraseña");
            }

            message.setContent(strcomentario, "text/html");
            Transport t = session.getTransport("smtp");
            t.connect(strmail, struser, strpass);
            t.sendMessage(message, message.getAllRecipients());

            // Cierre.
            t.close();
        } catch (Exception e) {
            log.error("ERROR en enviaMail : " + e.getMessage());
            log.error("ERROR en enviaMail : " + e.getLocalizedMessage());
            log.error("ERROR en enviaMail : " + e);
        }
    }

    public List<UsuarioPerfil> getLstUsuarioPerfil() {
        return lstUsuarioPerfil;
    }

    public void setLstUsuarioPerfil(List<UsuarioPerfil> lstUsuarioPerfil) {
        this.lstUsuarioPerfil = lstUsuarioPerfil;
    }

    public UsuarioPerfil getSelectedUsuarioPerfil() {
        return selectedUsuarioPerfil;
    }

    public void setSelectedUsuarioPerfil(UsuarioPerfil selectedUsuarioPerfil) {
        this.selectedUsuarioPerfil = selectedUsuarioPerfil;
    }

    public TreeNode getModuloTree() {
        return moduloTree;
    }

    public void setModuloTree(TreeNode moduloTree) {
        this.moduloTree = moduloTree;
    }

    public TreeNode getSelectedModuloNode() {
        return selectedModuloNode;
    }

    public void setSelectedModuloNode(TreeNode selectedModuloNode) {
        this.selectedModuloNode = selectedModuloNode;
    }

    public Modulo getSelectedModuloPerfil() {
        return selectedModuloPerfil;
    }

    public void setSelectedModuloPerfil(Modulo selectedModuloPerfil) {
        this.selectedModuloPerfil = selectedModuloPerfil;
    }

    public DualListModel<Perfil> getPerfiles() {
        return perfiles;
    }

    public void setPerfiles(DualListModel<Perfil> perfiles) {
        this.perfiles = perfiles;
    }

    public DualListModel<Opcion> getOpciones() {
        return opciones;
    }

    public void setOpciones(DualListModel<Opcion> opciones) {
        this.opciones = opciones;
    }
    
    public void validarAsignarPerfil(){
        selectedModuloNode = null;
        selectedModuloPerfil = null;
        mapaPefiles = new HashMap<String, Perfil>();
        moduloTree = new DefaultTreeNode("root", null);
        try {
            List<Modulo> lstModuloInicial = getService().findByNamedQuery("Modulo.findOnlyNidModuloPadreAndFlgActivo", new Object[]{Constante.ESTADO_ACTIVO});
            for (Modulo modulo : lstModuloInicial) {
                TreeNode padre = new DefaultTreeNode(modulo, moduloTree);
            }
        } catch (ServiceException ex) {
            log.error("ERROR EN validarAsignarPerfil :"+ex.getMessage());
        }
        List<Perfil> source = new ArrayList<Perfil>();
        List<Perfil> target = new ArrayList<Perfil>();
        for (UsuarioPerfil usuPerfil : lstUsuarioPerfil) {
            if(usuPerfil.getFlgActivo().equals(Constante.ESTADO_ACTIVO)){
                target.add(usuPerfil.getNidPerfil());
            }
            mapaPefiles.put(usuPerfil.getNidPerfil().getId().toString(), usuPerfil.getNidPerfil());
        }
        perfiles = new DualListModel<Perfil>(source, target);
    }
    
    public void onNodeSelectActivos(NodeSelectEvent event) {
        if(event.getTreeNode() != null){
            TreeNode node = event.getTreeNode();
            selectedModuloNode = node;
            selectedModuloPerfil = (Modulo) node.getData();
            node.setExpanded(true);
            List<Modulo> lstModuloHijos = new ArrayList<Modulo>();
            try {
                selectedModuloNode.getChildren().clear();
                lstModuloHijos = getService().findByNamedQuery("Modulo.findByNidModuloPadreAndFlgActivo", new Object[]{selectedModuloPerfil.getId(), Constante.ESTADO_ACTIVO});
                for (Modulo modulo : lstModuloHijos) {
                    TreeNode hijo = new DefaultTreeNode(modulo, selectedModuloNode);
                }
                List<Perfil> lstSourcePerfiles = new ArrayList<Perfil>();
                List<Perfil> lstPerfilesPorModulo = getService().findByNamedQuery("Perfil.findByNidModuloAndFlgActivo", new Object[]{selectedModuloPerfil.getId(), selectedUsuario.getTipUsuario(), Constante.ESTADO_ACTIVO});
                
                List<Perfil> target = new ArrayList<Perfil>();
                for (Object NIdPerfil : perfiles.getTarget()) {
                    if(NIdPerfil instanceof String){
                        if(mapaPefiles.containsKey(NIdPerfil.toString())){
                            target.add(mapaPefiles.get(NIdPerfil.toString()));
                        }
                    }else{
                        target.add((Perfil)NIdPerfil);
                    }
                }
                for (Perfil perfil : lstPerfilesPorModulo) {
                    mapaPefiles.put(perfil.getId().toString(), perfil);
                    if(existePerfil(target, perfil.getId()) == null){
                        lstSourcePerfiles.add(perfil);
                    }
                }
                perfiles = new DualListModel<Perfil>(lstSourcePerfiles, target);
            } catch (ServiceException ex) {
                log.error("ERROR EN onNodeSelectActivos: " + ex);
            }
        }
    }
    
    public void listarPerfilesPorModulo(){
        try {
            List<Perfil> lstSourcePerfiles = new ArrayList<Perfil>();
            List<Perfil> lstPerfilesPorModulo = new ArrayList<Perfil>();
            if(selectedModuloPerfil != null){
                lstPerfilesPorModulo = getService().findByNamedQuery("Perfil.findByNidModuloAndFlgActivo", new Object[]{selectedModuloPerfil.getId(), selectedUsuario.getTipUsuario(), Constante.ESTADO_ACTIVO});
            }
            List<Perfil> target = new ArrayList<Perfil>();
            for (Object NIdPerfil : perfiles.getTarget()) {
                if (NIdPerfil instanceof String) {
                    if (mapaPefiles.containsKey(NIdPerfil.toString())) {
                        target.add(mapaPefiles.get(NIdPerfil.toString()));
                    }
                } else {
                    target.add((Perfil) NIdPerfil);
                }
            }
            for (Perfil perfil : lstPerfilesPorModulo) {
                mapaPefiles.put(perfil.getId().toString(), perfil);
                if (existePerfil(target, perfil.getId()) == null) {
                    lstSourcePerfiles.add(perfil);
                }
            }
            perfiles = new DualListModel<Perfil>(lstSourcePerfiles, target);
        } catch (ServiceException ex) {
            log.error("ERROR EN listarPerfilesPorModulo: " + ex);
        }
    }
    
    public Perfil existePerfil(List<Perfil> lista, Long NIdPerfil) {
        for (Perfil pe : lista) {
            if (pe.getId().equals(NIdPerfil)) {
                return pe;
            }
        }
        return null;
    }
    
    public void personalizaPerfil(){
        FacesContext context = FacesContext.getCurrentInstance();
        Map mapaConext = context.getExternalContext().getRequestParameterMap();
        String sId = (String) mapaConext.get("id");
        RequestContext Rcontext = RequestContext.getCurrentInstance();
        String NIdPerfil="0";
        if(!sId.equals("")){
            NIdPerfil = sId.toString();
        }
        UsuarioPerfil usuarioPerfil = null;
        try {
             usuarioPerfil = (UsuarioPerfil) getService().findByNamedQueryUniqueRow("UsuarioPerfil.findByNidUsuarioAndNidPerfil", new Object[]{((Usuario) getBean()).getId(), Long.parseLong(NIdPerfil)});
        } catch (Exception e) {
            log.error("ERROR EN personalizaPerfil = "+e.getMessage());
        }
        if(usuarioPerfil == null){
            setMessageError(new Exception("Debe registrar el perfil antes de personalizarlo"));
        }else{
            selectedUsuarioPerfil = usuarioPerfil;
            selectedPersonalizaPerfil = usuarioPerfil;
            if(selectedPersonalizaPerfil.getFlgActivo().equals(Constante.ESTADO_ACTIVO)){
                BActivoPerfil = true;
            }else{
                BActivoPerfil = false;
            }
            muestraObservacionPerfil();
            if(selectedPersonalizaPerfil.getFlgHorarioRestringido().equals(Constante.ESTADO_ACTIVO)){
                BHorarioPerfil = true;
            }else{
                BHorarioPerfil = false;
            }
            if(selectedPersonalizaPerfil.getFlgConsulta().equals(Constante.FLAG_CONSULTA)){
                BTipoAcceso = true;
            }else{
                BTipoAcceso = false;
            }
            cargaUnidadOrganizacionalSinEvento();
            Rcontext.execute("detallePerfil.show()");
        }
    }
    
    public void limpiraPersonalizarPerfil(){
        selectedUsuarioPerfil =  null;
        opcionTree = new DefaultTreeNode("root", null);
        selectedOpcionNode = null;
        selectedUsuarioOpcion = null;
        lstUsuarioAccion = new ArrayList<UsuarioAutorizacion>();
        selectedUsuarioAccion = null;
        tituloPanelOpciones = "Opciones Asignadas";
        tituloPanelAcciones = "Acciones Asignadas";
    }
    
    public void validaModificarPerfil(){
        RequestContext context = RequestContext.getCurrentInstance();
        if (this.selectedUsuarioPerfil == null) {
            setMessageError(new Exception("Debe seleccionar un perfil"));
        } else {
            UsuarioPerfil usuarioPerfil = null;
            try {
                 usuarioPerfil = (UsuarioPerfil) getService().findById(UsuarioPerfil.class, selectedUsuarioPerfil.getId());
            } catch (Exception e) {
                log.error("ERROR EN personalizaPerfil = "+e.getMessage());
            }
            selectedPersonalizaPerfil = usuarioPerfil;
            if(selectedPersonalizaPerfil.getFlgActivo().equals(Constante.ESTADO_ACTIVO)){
                BActivoPerfil = true;
            }else{
                BActivoPerfil = false;
            }
            muestraObservacionPerfil();
            if(selectedPersonalizaPerfil.getFlgHorarioRestringido().equals(Constante.ESTADO_ACTIVO)){
                BHorarioPerfil = true;
            }else{
                BHorarioPerfil = false;
            }
            if(selectedPersonalizaPerfil.getFlgConsulta().equals(Constante.FLAG_CONSULTA)){
                BTipoAcceso = true;
            }else{
                BTipoAcceso = false;
            }
            cargaUnidadOrganizacionalSinEvento();
            context.execute("detallePerfil.show()");
        }
    }
    
    public void cargaUnidadOrganizacional(ValueChangeEvent event){
        Object objNew = event.getNewValue();
        if(objNew != null){
            selectedPersonalizaPerfil.setCodZonal(objNew.toString());
        }
        cargaUnidadOrganizacionalSinEvento();
    }
    
    public void cargaUnidadOrganizacionalSinEvento(){
        lstComboUnidadOrganizacional = new ArrayList<UnidadOrganizacional>();
        if(selectedPersonalizaPerfil.getCodZonal().equals(Constante.CODIGO_SEDE_CENTRAL)){
            try{
                lstComboUnidadOrganizacional = getService().findByNamedQuery("UnidadOrganizacional.findByCodZonal", new Object[]{ selectedPersonalizaPerfil.getCodZonal() });
                log.info("lstComboUnidadOrganizacional="+lstComboUnidadOrganizacional.size());
            } catch (ServiceException e) {
                log.error("ERROR EN cargaUnidadOrganizacionalSinEvento = "+e.getMessage());
            }
        }else{
            selectedPersonalizaPerfil.setCodUnidad(Constante.NO_OPTION_SELECTED);
        }
    }
    
    public void muestraObservacionPerfil() {
        BMuestraObsPerfil = (BActivoPerfil)?false:true;
    }
    
    public void guardarUsuarioPerfil() throws Exception {
        List<UsuarioPerfil> lstUsuarioPerfilTmp = new ArrayList<UsuarioPerfil>();
        lstUsuarioPerfilTmp = getService().findByNamedQuery("UsuarioPerfil.findByNidUsuario", new Object[]{selectedUsuario.getId()});
        ControlAcceso control = ((ControlAcceso) getSpringBean(Constante.SESSION_ACCESO));
        
        List<Perfil> target = new ArrayList<Perfil>();
        for (Object NIdPerfil : perfiles.getTarget()) {
            if (NIdPerfil instanceof String) {
                if (mapaPefiles.containsKey(NIdPerfil.toString())) {
                    target.add(mapaPefiles.get(NIdPerfil.toString()));
                }
            } else {
                target.add((Perfil) NIdPerfil);
            }
        }
        for (UsuarioPerfil usuarioPerfil : lstUsuarioPerfilTmp) {
            //si no esta, se debe desactivar
            if (existePerfil(target, usuarioPerfil.getNidPerfil().getId()) == null) {
                List<UsuarioAutorizacion> autorizaciones = getService().findByNamedQuery("UsuarioAutorizacion.findByNidUsuarioPerfilAndFlgActivo", new Object[]{usuarioPerfil.getId(), Constante.ESTADO_ACTIVO});
                for (UsuarioAutorizacion ua : autorizaciones) {
                    try {
                        ua.setFlgActivo(Constante.ESTADO_INACTIVO);
                        ua.setNIdCtrlAccesoWeb(control.getId());
                        getService().executeUpdate("UsuarioAutorizacion.updateFlgActivo", new Object[]{ua.getFlgActivo(), ua.getNIdCtrlAccesoWeb(), ua.getUsuarioAutorizacionPK().getNidAccion(), ua.getUsuarioAutorizacionPK().getNidUsuarioPerfil()});
                    } catch (Exception e) {
                        log.error("ERROR en quitar autorizaciones =" + e);
                    }
                }
                if(usuarioPerfil.getFlgActivo().equals(Constante.ESTADO_ACTIVO)){
                    usuarioPerfil.setFlgActivo(Constante.ESTADO_INACTIVO);
                    usuarioPerfil.setNIdCtrlAccesoWeb(control.getId());
                    getService().save(usuarioPerfil);
                }
            }
        }
        Usuario usuario = (Usuario) getBean();
        String SCodUnidad = null;
        if(usuario.getNidPersonal() != null){
            Personal personal = (Personal) getService().findById(Personal.class, usuario.getNidPersonal());
            if(personal != null){
                if(personal.getCodUnidad() != null){
                    SCodUnidad = personal.getCodUnidad().getCodUnidad();
                }
            }
        }
        UsuarioPerfil usuarioPerfil = null;
        for (Perfil perfil : target) {
            usuarioPerfil = existeUsuarioPerfil(lstUsuarioPerfilTmp, perfil.getId());
            if (usuarioPerfil == null) {
                usuarioPerfil = new UsuarioPerfil();
                usuarioPerfil.setFlgActivo(Constante.ESTADO_ACTIVO);
                usuarioPerfil.setFlgConsulta(Constante.FLAG_CONSULTA);
                usuarioPerfil.setFlgCaduca(Constante.ESTADO_INACTIVO);
                usuarioPerfil.setNidUsuario(usuario);
                usuarioPerfil.setNidPerfil(perfil);
                usuarioPerfil.setCodZonal(usuario.getCodZonal());
                usuarioPerfil.setCodUnidad(SCodUnidad);
                usuarioPerfil.setFlgHorarioRestringido(Constante.ESTADO_INACTIVO);
                usuarioPerfil.setNIdCtrlAccesoWeb(control.getId());
                usuarioPerfil = (UsuarioPerfil)getService().save(usuarioPerfil);
                //Se agrega las autorizaciones
                UsuarioAutorizacion autorizacion= null;
                GregorianCalendar gcal = (GregorianCalendar) GregorianCalendar.getInstance();
                List<Object[]> listaObj = getService().findByNamedQuery("PerfilOpcion.findAccionByNidPerfil", new Object[]{Constante.ESTADO_ACTIVO, Constante.ESTADO_ACTIVO, perfil.getId()});
                Accion accion = null;
                String SflgConsulta = "";
                for (Object[] obj : listaObj) {
                    accion = (Accion)obj[0];
                    SflgConsulta = obj[1].toString();
                    autorizacion = new UsuarioAutorizacion();
                    autorizacion.setAccion(accion);
                    autorizacion.setFecInicio(gcal.getTime());
                    autorizacion.setFlgActivo(Constante.ESTADO_ACTIVO);
                    autorizacion.setFlgConsulta(SflgConsulta);
                    autorizacion.setFlgCaduca(Constante.ESTADO_INACTIVO);
                    autorizacion.setUsuarioPerfil(usuarioPerfil);
                    autorizacion.setNIdCtrlAccesoWeb(control.getId());
                    autorizacion.setUsuarioAutorizacionPK(new UsuarioAutorizacionPK(accion.getId(), usuarioPerfil.getId()));
                    getService().save(autorizacion);
                }                
            }else{
                if(usuarioPerfil.getFlgActivo().equals(Constante.ESTADO_INACTIVO)){
                    usuarioPerfil.setFlgActivo(Constante.ESTADO_ACTIVO);
                    usuarioPerfil.setFlgCaduca(Constante.ESTADO_INACTIVO);
                    usuarioPerfil.setTxtObservacion(null);
                    usuarioPerfil.setNIdCtrlAccesoWeb(control.getId());
                    getService().save(usuarioPerfil);
                    List<UsuarioAutorizacion> autorizaciones = getService().findByNamedQuery("UsuarioAutorizacion.findByNidUsuarioPerfilAndFlgActivo", new Object[]{usuarioPerfil.getId(), Constante.ESTADO_INACTIVO});
                    for (UsuarioAutorizacion ua : autorizaciones) {
                        ua.setNIdCtrlAccesoWeb(control.getId());
                        ua.setFlgActivo(Constante.ESTADO_ACTIVO);
                        getService().executeUpdate("UsuarioAutorizacion.updateFlgActivo", new Object[]{ua.getFlgActivo(), ua.getNIdCtrlAccesoWeb(), ua.getUsuarioAutorizacionPK().getNidAccion(), ua.getUsuarioAutorizacionPK().getNidUsuarioPerfil()});
                        //getService().save(ua);
                    }
                }
            }
        }
        listarPerfilesPorModulo();
        lstUsuarioPerfil = getService().findByNamedQuery("UsuarioPerfil.findByNidUsuario", new Object[]{selectedUsuario.getId()});
        setMessageSuccess("Se actualizaron los perfiles  del usuario " + "'" + usuario.getNombreCompleto() + "'" + " satisfactoriamente.");
    }
    
    public UsuarioPerfil existeUsuarioPerfil(List<UsuarioPerfil> lista, Long NIdPerfil) {
        for (UsuarioPerfil pe : lista) {
            if (pe.getNidPerfil().getId().equals(NIdPerfil)) {
                return pe;
            }
        }
        return null;
    }
    
    public void saveUsuarioPerfil(){
        selectedPersonalizaPerfil.setFlgActivo((BActivoPerfil)?Constante.ESTADO_ACTIVO:Constante.ESTADO_INACTIVO);
        selectedPersonalizaPerfil.setFlgConsulta((BTipoAcceso)?Constante.ESTADO_ACTIVO:Constante.ESTADO_INACTIVO);
        selectedPersonalizaPerfil.setFlgHorarioRestringido((BHorarioPerfil)?Constante.ESTADO_ACTIVO:Constante.ESTADO_INACTIVO);
        if(validateUsuarioPerfil()){
            ControlAcceso control = ((ControlAcceso) getSpringBean(Constante.SESSION_ACCESO));
            if (selectedPersonalizaPerfil.getFlgActivo().equals(Constante.ESTADO_ACTIVO) && !esNuevo) {
                selectedPersonalizaPerfil.setTxtObservacion(null);
            }
            if(selectedPersonalizaPerfil.getCodUnidad().equals(Constante.NO_OPTION_SELECTED)){
                selectedPersonalizaPerfil.setCodUnidad(null);
            }
            selectedPersonalizaPerfil.setNIdCtrlAccesoWeb(control.getId());
            selectedPersonalizaPerfil.setFlgCaduca(Constante.ESTADO_INACTIVO);
            try {
                getService().save(selectedPersonalizaPerfil);
                lstUsuarioPerfil = getService().findByNamedQuery("UsuarioPerfil.findByNidUsuario", new Object[]{selectedUsuario.getId()});
            } catch (Exception e) {
                log.error("ERROR EN saveUsuarioPerfil ="+e.getMessage());
            }
            String StipoConsulta = (selectedPersonalizaPerfil.getFlgConsulta().equals(Constante.FLAG_CONSULTA)?"Consulta":"NO CONSULTA");
            selectedUsuarioPerfil = selectedPersonalizaPerfil;
            setMessageSuccess("Se actualizó el perfil " + "'" + selectedPersonalizaPerfil.getNidPerfil().getTxtPerfil() + "'" + " satisfactoriamente. / Tipo de Acceso : "+StipoConsulta);
            listaOpcionesDePerfilSinEvento();
        }
    }
    
    public boolean validateUsuarioPerfil() {
        boolean success = true;
        
        if(selectedPersonalizaPerfil.getCodZonal().equals(Constante.NO_OPTION_SELECTED)){
            setMessageError(new Exception("Se debe seleccionar la Unidad Territorial."));
            success = false;
            return success;
        }
        if(selectedPersonalizaPerfil.getFlgActivo().equals(Constante.ESTADO_INACTIVO)) {
            if (selectedPersonalizaPerfil.getTxtObservacion() == null ){
                selectedPersonalizaPerfil.setTxtObservacion("");
            }
            if(selectedPersonalizaPerfil.getTxtObservacion().equals("")){
                setMessageError(new Exception("Se debe ingresar la observación."));
                success = false;
                return success;
            }
        }
        return success;
    }
    
    public void validaAsignarHorarioPerfil() {
        RequestContext context = RequestContext.getCurrentInstance();
        if (this.selectedUsuarioPerfil == null) {
            setMessageError(new Exception("Debe seleccionar un perfil"));
        } else {
            if(this.selectedUsuarioPerfil.getFlgActivo().equals(Constante.ESTADO_INACTIVO)){
                setMessageError(new Exception("El perfil del usuario no se encuentra activo"));
            }else{
                selectedPersonalizaPerfil = selectedUsuarioPerfil;
                validaConfiguraHorarioPerfil();
                muestraObservacionHorarioPerfil();
                context.execute("detalleHorarioPerfil.show()");
            }
        }
    }
    
    public void validaConfiguraHorarioPerfil() {
        lstUsuarioHorarioPerfil = new ArrayList<HorarioPerfil>();
        try {
            lstUsuarioHorarioPerfil = getService().findByNamedQuery("HorarioPerfil.findAllByNIdUsuarioPerfil", new Object[]{selectedPersonalizaPerfil.getId()});
        } catch (Exception e) {
            log.error("ERROR EN validaConfiguraHorarioPerfil = " + e.getMessage());
        }
        selectedHorarioPerfil = new HorarioPerfil();
        esNuevo = true;
        selectedHorarioPerfil.setFlgActivo(Constante.ESTADO_ACTIVO);
        if (!lstUsuarioHorarioPerfil.isEmpty()) {
            selectedHorarioPerfil = lstUsuarioHorarioPerfil.get(0);
            esNuevo = false;
        }
        if (selectedHorarioPerfil.getFlgActivo().equals(Constante.ESTADO_ACTIVO)) {
            BActivoHorarioPerfil = true;
        } else {
            BActivoHorarioPerfil = false;
        }
    }
    
    public void muestraObservacionHorarioPerfil() {
        BMuestraObsHorarioPerfil = (BActivoHorarioPerfil)?false:true;
    }
    
    public void guardarUsuarioHorarioPerfil() throws Exception {
        if (selectedHorarioPerfil.getFecHoraInicio() == null) {
            setMessageError(new Exception("Se debe ingresar la fecha de inicio."));
            return;
        }
        if (selectedHorarioPerfil.getFecHoraFin() == null) {
            setMessageError(new Exception("Se debe ingresar la fecha de fin."));
            return;
        }
        if(selectedHorarioPerfil.getFecHoraFin().before(selectedHorarioPerfil.getFecHoraInicio())){
            setMessageError(new Exception("La fecha de inicio no puede ser mayor a la fecha de fin."));
            return;
        }
        ControlAcceso control = ((ControlAcceso) getSpringBean(Constante.SESSION_ACCESO));
        selectedHorarioPerfil.setFlgActivo((BActivoHorarioPerfil)?Constante.ESTADO_ACTIVO:Constante.ESTADO_INACTIVO);
        if(selectedHorarioPerfil.getFlgActivo().equals(Constante.ESTADO_INACTIVO)) {
            if (selectedHorarioPerfil.getTxtObservacion() == null ){
                selectedHorarioPerfil.setTxtObservacion("");
            }
            if(selectedHorarioPerfil.getTxtObservacion().equals("")){
                setMessageError(new Exception("Se debe ingresar la observación."));
                return;
            }
        }else{
            selectedHorarioPerfil.setTxtObservacion(null);
        }
        selectedHorarioPerfil.setNIdCtrlAccesoWeb(control.getId());
        selectedHorarioPerfil.setNidUsuarioPerfil(selectedUsuarioPerfil);
        guardarAuditoriaUsuarioHorarioPerfil(selectedHorarioPerfil);
        //getService().save(selectedHorarioPerfil);
        
        selectedPersonalizaPerfil.setFlgHorarioRestringido(selectedHorarioPerfil.getFlgActivo());
        selectedPersonalizaPerfil.setNIdCtrlAccesoWeb(control.getId());
        getService().save(selectedPersonalizaPerfil);

        setMessageSuccess("Se actualizó el horario satisfactoriamente.");
    }
    
    public void guardarAuditoriaUsuarioHorarioPerfil(HorarioPerfil selectedHorarioPerfil){
        Object bean = getBean();
        try {
            setBean(selectedHorarioPerfil);
            if(esNuevo){
                super.beforeSave(null);
                super.doSave(null);
                log.info("End of Transaction: 'Save'");
            }else{
                super.beforeUpdate(null);
                super.doUpdate(null);
                log.info("End of Transaction: 'Update'");
            }
        } catch (Exception e) {
            log.error("ERROR EN guardarAuditoriaUsuarioHorarioPerfil:"+e.getMessage());
        }
        setBean(bean);
    }
    
    public void loadHijoTreePerfilBase(TreeNode hijo, Modulo moHijo, List<Long> perfiles) throws ServiceException {
        //Se cargan las opciones del modulo
        List<Opcion> lstOpcionPadre = getService().findByNamedQuery("Opcion.findOnlyNidOpcionPadreAndFlgActivo", new Object[]{moHijo.getId(), Constante.ESTADO_ACTIVO});
        for (Opcion opPadre : lstOpcionPadre) {
            TreeNode opcionPadre = new DefaultTreeNode("document",opPadre, hijo);
            opcionPadre.setExpanded(false);
            loadOpcionesHijoTree(opcionPadre, opPadre, moHijo);
        }
        //se listan los sub modulos
        List<Modulo> lstModuloHijos = getService().findByNamedQuery("Modulo.findByNidModuloPadreAndFlgActivo", new Object[]{moHijo.getId(), Constante.ESTADO_ACTIVO});
        for (Modulo modulo : lstModuloHijos) {
            TreeNode nieto = new DefaultTreeNode(modulo, hijo);
            nieto.setExpanded(true);
            loadHijoTreePerfilBase(nieto, modulo, perfiles);
        }
    }
    
    public void loadOpcionesHijoTree(TreeNode hijo, Opcion opHijo, Modulo moPadre) throws ServiceException {
        List<Opcion> lstOpcionHijos = getService().findByNamedQuery("Opcion.findByNidOpcionPadreAndFlgActivo", new Object[]{opHijo.getId(), moPadre.getId(), Constante.ESTADO_ACTIVO});
        for (Opcion opcion : lstOpcionHijos) {
            TreeNode nieto = new DefaultTreeNode("document",opcion, hijo);
            nieto.setExpanded(true);
            loadOpcionesHijoTree(nieto, opcion, moPadre);
        }
    }
    
    public void validarAsignarOpcion() throws ServiceException{
        RequestContext context = RequestContext.getCurrentInstance();
        if (this.selectedUsuarioPerfil == null) {
            setMessageError(new Exception("Debe seleccionar un perfil"));
        } else {
            if(this.selectedUsuarioPerfil.getFlgActivo().equals(Constante.ESTADO_INACTIVO)){
                setMessageError(new Exception("El perfil del usuario no se encuentra activo"));
            }else{
                boolean BAsignado = false;
                boolean BesBase = false;
                String codZonal = "";
                if (selectedUsuarioPerfil.getNidPerfil().getFlgBase().equals(Constante.FLAG_PERFIL_BASE)) {
                    BesBase = true;
                    if (selectedUsuarioPerfil.getCodZonal() != null) {
                        codZonal = selectedUsuarioPerfil.getCodZonal().trim();
                    }
                }
                /*for (UsuarioPerfil usuarioPerfil : lstUsuarioPerfil) {
                    if(!usuarioPerfil.getId().equals(selectedUsuarioPerfil.getId())){
                        if (usuarioPerfil.getNidPerfil().getNidModulo().getId().equals(selectedUsuarioPerfil.getNidPerfil().getNidModulo().getId())) {
                            if (BesBase) {
                                if (usuarioPerfil.getCodZonal().equals(codZonal)) {
                                    BAsignado = true;
                                    setMessageError(new Exception("Todas las opciones del módulo " + selectedUsuarioPerfil.getNidPerfil().getNidModulo().getTxtModulo()+" ya han sido activadas"));
                                    break;
                                }
                            }
                        }
                    }
                }*/
                if(!BAsignado){
                    validaConfigurarOpcion();
                    context.execute("asignaOpcion.show()");
                }
            }
        }
    }
    
    public void validaConfigurarOpcion() throws ServiceException{
        selectedModuloNode = null;
        selectedModuloPerfil = null;
        
        moduloTree = new DefaultTreeNode("root", null);
        Modulo moduloPadre = null;
        if (selectedUsuarioPerfil.getNidPerfil().getNidModulo().getNidModuloPadre() == null) {
            moduloPadre = selectedUsuarioPerfil.getNidPerfil().getNidModulo();
        } else {
            moduloPadre = getUsuarioService().getModuloPadre(selectedUsuarioPerfil.getNidPerfil().getNidModulo().getId());
        }
        TreeNode padre = new DefaultTreeNode(moduloPadre, moduloTree);
        padre.setExpanded(true);
        
        List<Long> idsPerfiles = new ArrayList<Long>();
        for (UsuarioPerfil usuarioPerfil : lstUsuarioPerfil) {
            idsPerfiles.add(usuarioPerfil.getNidPerfil().getId());
        }
        //Comenzar a realizar el arbol
        loadHijoTreePerfilBase(padre, moduloPadre, idsPerfiles);
        listaOpcionesAutorizadas = new ArrayList<Opcion>();
        mapaOpciones = new HashMap<String, Opcion>();
        NIdPerfilSeleccionado = selectedUsuarioPerfil.getNidPerfil().getId();
        onNodeOpcionSelectSinEvento(padre);
        selectedModuloNode = padre;
    }
    
    public void onNodeOpcionSelectSinEvento(TreeNode node) {
        if (node.getChildCount() >= 0) {
            List<TreeNode> hijosNodo = node.getChildren();
            if (!hijosNodo.isEmpty()) {
                List<Long> idsPerfiles = new ArrayList<Long>();
                listaOpcionesAutorizadas = new ArrayList<Opcion>();
                boolean BesBase = false;
                String codZonal = "";
                if (selectedUsuarioPerfil.getNidPerfil().getFlgBase().equals(Constante.FLAG_PERFIL_BASE)) {
                    BesBase = true;
                    if (selectedUsuarioPerfil.getCodZonal() != null) {
                        codZonal = selectedUsuarioPerfil.getCodZonal().trim();
                    }
                }
                for (UsuarioPerfil usuarioPerfil : lstUsuarioPerfil) {
                    if (usuarioPerfil.getNidPerfil().getNidModulo().getId().equals(selectedUsuarioPerfil.getNidPerfil().getNidModulo().getId())) {
                        if (BesBase) {
                            if (usuarioPerfil.getCodZonal().equals(codZonal)) {
                                idsPerfiles.add(usuarioPerfil.getNidPerfil().getId());
                            }
                        } else {
                            idsPerfiles.add(usuarioPerfil.getNidPerfil().getId());
                        }
                    }
                }
                Modulo moduloSelected = null;
                Opcion opcionPadreSelected = null;
                String SQuery = "";

                List<Opcion> lstOpcionPadre = new ArrayList<Opcion>();
                //si es modulo
                if (node.getData() instanceof Modulo) {
                    //si el primero es opcion
                    if (hijosNodo.get(0).getData() instanceof Opcion) {
                        moduloSelected = (Modulo) node.getData();
                        if (BesBase) {
                            SQuery = "PerfilOpcion.findOnlyOpcionPadreByNidPerfilBase";
                        } else {
                            SQuery = "PerfilOpcion.findOnlyOpcionPadreByNidPerfil";
                        }
                        try {
                            lstOpcionPadre = getService().findByNamedQuery(SQuery, new Object[]{moduloSelected.getId(), Constante.ESTADO_ACTIVO, (BesBase) ? idsPerfiles : NIdPerfilSeleccionado});
                        } catch (Exception e) {
                            log.error("ERROR EN onNodeOpcionSelect=" + e.getMessage());
                        }
                    }
                } else {
                    //si es opcion
                    opcionPadreSelected = (Opcion) node.getData();
                    moduloSelected = opcionPadreSelected.getNidModulo();
                    if (BesBase) {
                        SQuery = "PerfilOpcion.findOpcionByNidPerfilBase";
                    } else {
                        SQuery = "PerfilOpcion.findOpcionByNidPerfil";
                    }
                    try {
                        lstOpcionPadre = getService().findByNamedQuery(SQuery, new Object[]{moduloSelected.getId(), Constante.ESTADO_ACTIVO, (BesBase) ? idsPerfiles : NIdPerfilSeleccionado, opcionPadreSelected.getId()});
                    } catch (Exception e) {
                        log.error("ERROR EN onNodeOpcionSelect=" + e.getMessage());
                    }
                }
                UsuarioAutorizacion autorizacion = null;
                for (Opcion op : lstOpcionPadre) {
                    try {
                        autorizacion = (UsuarioAutorizacion) getService().findByNamedQueryUniqueRow("UsuarioAutorizacion.findByNidUsuarioPerfilAndNidOpcion", new Object[]{selectedUsuarioPerfil.getId(), op.getId(), Constante.ESTADO_ACTIVO, Constante.ESTADO_ACTIVO});
                    } catch (Exception e) {
                        autorizacion = null;
                        log.error("ERROR EN onNodeOpcionSelect=" + e.getMessage());
                    }
                    op.setFlgActivo(Constante.ESTADO_INACTIVO);
                    op.setBflgActivo(false);
                    if (autorizacion != null) {
                        op.setFlgActivo(Constante.ESTADO_ACTIVO);
                        op.setBflgActivo(true);
                        op.setBflgConsulta((autorizacion.getFlgConsulta().equals(Constante.ESTADO_ACTIVO) ? true : false));
                    }
                    mapaOpciones.put(op.getId().toString(), op);
                    listaOpcionesAutorizadas.add(op);
                }
            }
        }
    }
    
    public void onNodeOpcionSelect(NodeSelectEvent event) {
        if(event.getTreeNode() != null){
            listaOpcionesAutorizadas = new ArrayList<Opcion>();
            TreeNode node = event.getTreeNode();
            onNodeOpcionSelectSinEvento(node);
        }
    }
    
    public void agregaOpcionParaUsuarioPerfil(Opcion opcion){
        if(!opcion.isBflgActivo()){
            opcion.setBflgConsulta(false);
        }else{
            if(selectedUsuarioPerfil.getFlgConsulta().equals(Constante.FLAG_CONSULTA)){
                opcion.setBflgConsulta(false);
            }else{
                opcion.setBflgConsulta(true);
            }
        }
        mapaOpciones.put(opcion.getId().toString(), opcion);
    }
    
    public void personalizaOpcion(Opcion opcion){
        RequestContext context = RequestContext.getCurrentInstance();
        lstUsuarioAutorizacion = new ArrayList<UsuarioAutorizacion>();
        try {
             lstUsuarioAutorizacion = getService().findByNamedQuery("UsuarioAutorizacion.findByNidAccionAndNidUsuarioPerfil", new Object[]{ opcion.getId(), selectedUsuarioPerfil.getId(), Constante.ESTADO_ACTIVO});
        } catch (Exception e) {
            log.error("ERROR EN personalizaOpcion = "+e.getMessage());
        }
        if(lstUsuarioAutorizacion.isEmpty()){
            setMessageError(new Exception("Debe registrar la opcion antes de personalizar las acciones"));
        }else{
            selectedUsuarioOpcion = new PerfilOpcion();
            selectedUsuarioOpcion.setPerfil(selectedUsuarioPerfil.getNidPerfil());
            selectedUsuarioOpcion.setOpcion(opcion);
            selectedUsuarioOpcion.setFlgConsulta(opcion.isBflgConsulta()?Constante.FLAG_CONSULTA:Constante.ESTADO_INACTIVO);
            selectedUsuarioAutorizacion = null;
            context.execute("asignaAccion.show()");
        }
    }
    
    public void listarAutorizaciones(){
        lstUsuarioAutorizacion = new ArrayList<UsuarioAutorizacion>();
        try {
             lstUsuarioAutorizacion = getService().findByNamedQuery("UsuarioAutorizacion.findByNidAccionAndNidUsuarioPerfil", new Object[]{ selectedUsuarioOpcion.getOpcion().getId(), selectedUsuarioPerfil.getId(), Constante.ESTADO_ACTIVO});
             lstUsuarioAccion = lstUsuarioAutorizacion;
             selectedUsuarioAccion = null;
        } catch (Exception e) {
            log.error("ERROR EN listarAutorizaciones = "+e.getMessage());
        }
    }
    
    public void validaLoadAutorizacion(UsuarioAutorizacion usuarioAutorizacion) {
        if (usuarioAutorizacion.getFlgActivo().equals(Constante.ESTADO_ACTIVO)) {
            BActivoAccion = true;
        } else {
            BActivoAccion = false;
        }
        if (usuarioAutorizacion.getFlgConsulta().equals(Constante.FLAG_CONSULTA)) {
            BTipoAccesoAccion = true;
        } else {
            BTipoAccesoAccion = false;
        }
    }
    
    public void loadAutorizacion() {
        RequestContext context = RequestContext.getCurrentInstance();
        if (this.selectedUsuarioAutorizacion == null) {
            setMessageError(new Exception("Debe seleccionar una acción"));
        } else {
            if(selectedUsuarioAutorizacion.getAccion().getFlgDefault().equals(Constante.ESTADO_ACTIVO)){
                setMessageError(new Exception("No se debe modificar la acción por defecto"));
            }else{
                validaLoadAutorizacion(selectedUsuarioAutorizacion);
                context.execute("detalleAutorizacion.show()");
            }
        }
    }
    
    public void loadAccionAsignada() {
        RequestContext context = RequestContext.getCurrentInstance();
        if (this.selectedUsuarioAccion == null) {
            setMessageError(new Exception("Debe seleccionar una acción"));
        } else {
            if(selectedUsuarioAccion.getAccion().getFlgDefault().equals(Constante.ESTADO_ACTIVO)){
                setMessageError(new Exception("No se debe modificar la acción por defecto"));
            }else{
                selectedUsuarioAutorizacion = selectedUsuarioAccion;
                validaLoadAutorizacion(selectedUsuarioAutorizacion);
                context.execute("detalleAutorizacion.show()");
            }
        }
    }
    
    public void saveAutorizacion() throws Exception{
        ControlAcceso control = ((ControlAcceso) getSpringBean(Constante.SESSION_ACCESO));
        selectedUsuarioAutorizacion.setFlgActivo((BActivoAccion)?Constante.ESTADO_ACTIVO:Constante.ESTADO_INACTIVO);
        selectedUsuarioAutorizacion.setFlgConsulta((BTipoAccesoAccion)?Constante.ESTADO_ACTIVO:Constante.ESTADO_INACTIVO);
        selectedUsuarioAutorizacion.setNIdCtrlAccesoWeb(control.getId());
        
        if(selectedUsuarioAutorizacion.getFecInicio() != null && selectedUsuarioAutorizacion.getFecFin() != null){
            if(selectedUsuarioAutorizacion.getFecFin().before(selectedUsuarioAutorizacion.getFecInicio())){
                setMessageError(new Exception("La Fecha de Inicio no puede ser mayor a la Fecha de Término."));
                return;
            }
        }
        getService().save(selectedUsuarioAutorizacion);
        setMessageSuccess("Se actualizó la acción satisfactoriamente.");
    }
    
    public void guardarUsuarioPerfilOpciones() throws Exception {
        boolean BesBase = false;
        Usuario usuario = (Usuario) getBean();
        UsuarioAutorizacion autorizacion = null;
        ControlAcceso control = ((ControlAcceso) getSpringBean(Constante.SESSION_ACCESO));
        lstUsuarioAutorizacion = new ArrayList<UsuarioAutorizacion>();
        List<Accion> lstAccionDeOpcion;
        if (selectedUsuarioPerfil.getNidPerfil().getFlgBase().equals(Constante.FLAG_PERFIL_BASE)) {
            BesBase = true;
        }
        
        /**
         * Validación de Opciones Padre
         */
        if(!listaOpcionesAutorizadas.isEmpty()){
            for (Opcion opcionAValidar : listaOpcionesAutorizadas) {
                if(opcionAValidar.getNidOpcionPadre() != null){
                    List lista = getService().findByNamedQuery("UsuarioAutorizacion.findByNidUsuarioPerfilAndNidOpcion", new Object[]{selectedUsuarioPerfil.getId(), opcionAValidar.getNidOpcionPadre().getId(), Constante.ESTADO_ACTIVO, Constante.ESTADO_ACTIVO});
                    System.out.println(">>>>>>>>>Validación de Opciones Padre = "+lista.isEmpty());
                    if(lista.isEmpty()){
                        setMessageError("Debe haber ingresado las opciones padre");
                        return;
                    }
                }
            }
        }
        /**
         * Validación de Opciones Padre Fin
         */
        for (Opcion opcion : listaOpcionesAutorizadas) {
            //Se modifican las autorizaciones
            if(mapaOpciones.containsKey(opcion.getId().toString())){
                opcion = mapaOpciones.get(opcion.getId().toString());
            }
            //NO DEBE CAMBIAR TODAS LAS OPCIONES
            lstUsuarioAutorizacion = getService().findByNamedQuery("UsuarioAutorizacion.findByNidOpcionAndNidUsuarioPerfil", new Object[]{ selectedUsuarioPerfil.getId(), opcion.getId()});
            for (UsuarioAutorizacion autoriza : lstUsuarioAutorizacion) {
                autoriza.setFlgActivo((opcion.isBflgActivo())?Constante.ESTADO_ACTIVO:Constante.ESTADO_INACTIVO);
                autoriza.setFlgConsulta((opcion.isBflgConsulta())?Constante.ESTADO_ACTIVO:Constante.ESTADO_INACTIVO);
                autoriza.setNIdCtrlAccesoWeb(control.getId());        
                getService().executeUpdate("UsuarioAutorizacion.updateFlgConsulta", new Object[]{autoriza.getFlgActivo(), autoriza.getFlgConsulta() ,autoriza.getNIdCtrlAccesoWeb(), autoriza.getUsuarioAutorizacionPK().getNidAccion(), autoriza.getUsuarioAutorizacionPK().getNidUsuarioPerfil()});
            }
            //Acciones que no estan en el perfil
            //if(opcion.isBflgActivo() && BesBase){
            if(opcion.isBflgActivo()){
                lstAccionDeOpcion = getService().findByNamedQuery("Accion.findByNotInUsuarioPerfil", new Object[]{opcion.getId(), Constante.ESTADO_ACTIVO, Constante.ESTADO_ACTIVO, selectedUsuarioPerfil.getId(), opcion.getId()});
                for (Accion accion : lstAccionDeOpcion) {
                    autorizacion = new UsuarioAutorizacion();
                    autorizacion.setUsuarioAutorizacionPK(new UsuarioAutorizacionPK(accion.getId(), selectedUsuarioPerfil.getId()));
                    autorizacion.setFecInicio(Constante.FECHA_ACTUAL);
                    autorizacion.setUsuarioPerfil(selectedUsuarioPerfil);
                    autorizacion.setFlgConsulta((opcion.isBflgConsulta())?Constante.ESTADO_ACTIVO:Constante.ESTADO_INACTIVO);
                    autorizacion.setFlgActivo(Constante.ESTADO_ACTIVO);
                    autorizacion.setFlgCaduca(Constante.ESTADO_INACTIVO);
                    autorizacion.setAccion(accion);
                    autorizacion.setNIdCtrlAccesoWeb(control.getId());
                    getService().save(autorizacion);
                }
            }
        }
        TreeNode selectedOpcionNodeTmp = selectedOpcionNode;
        listaOpcionesDePerfilSinEvento();
        if(selectedOpcionNode != null){
            selectedUsuarioOpcion = (PerfilOpcion) selectedOpcionNode.getData();
            listaAccionesDeOpcionDelPerfilSinEvento(selectedUsuarioOpcion);
        }
        selectedOpcionNode = selectedOpcionNodeTmp;
        setMessageSuccess("Se actualizaron las opciones del usuario " + "'" + usuario.getNombreCompleto() + "'" + " satisfactoriamente.");
    }
    
    public void validarAsignarInstancias() {
        RequestContext context = RequestContext.getCurrentInstance();
        if (this.selectedUsuario == null) {
            setMessageError(new Exception("Debe seleccionar un registro"));
        } else {
            if (this.selectedUsuario.getFlgActivo().equals(Constante.ESTADO_INACTIVO)) {
                setMessageError(new Exception("El usuario se encuentra desactivado"));
            }else{
                setBean(selectedUsuario);
                mapaInstancias = new HashMap<String, Instancia>();
                List<Instancia> source = new ArrayList<Instancia>();
                List<Instancia> target = new ArrayList<Instancia>();

                List<Instancia> sourceTmp = new ArrayList<Instancia>();
                List<UsuarioInstancia> lstUsuarioInstancia = new ArrayList<UsuarioInstancia>();
                try {
                    sourceTmp = getService().findByNamedQuery("Instancia.findByFlgActivo", new Object[]{Constante.ESTADO_ACTIVO});
                    lstUsuarioInstancia = getService().findByNamedQuery("UsuarioInstancia.findByNidUsuario", new Object[]{selectedUsuario.getId()});
                } catch (Exception e) { 
                    log.error("ERROR EN validarAsignarInstancias ="+e.getMessage());
                }
                for (UsuarioInstancia usuarioInstancia : lstUsuarioInstancia) {
                    if (usuarioInstancia.getFlgActivo().equals(Constante.ESTADO_ACTIVO)) {
                        target.add(usuarioInstancia.getInstancia());
                    }
                    mapaInstancias.put(usuarioInstancia.getInstancia().getId().toString(), usuarioInstancia.getInstancia());
                }
                for (Instancia instanciaTmp : sourceTmp) {
                    mapaInstancias.put(instanciaTmp.getId().toString(), instanciaTmp);
                    if(existeInstancia(target, instanciaTmp.getId()) == null){
                        source.add(instanciaTmp);
                    }
                }
                instancias = new DualListModel<Instancia>(source, target);
                context.execute("asignaInstancias.show()");
            }
        }
    }
    
    public Instancia existeInstancia(List<Instancia> lista, Long NIdInstancia) {
        for (Instancia instancia : lista) {
            if (instancia.getId().equals(NIdInstancia)) {
                return instancia;
            }
        }
        return null;
    }
    
    public void guardarUsuarioInstancia() throws Exception {
        Usuario usuario = (Usuario) getBean();
        Object bean = getBean();
        List<UsuarioInstancia> lstUsuarioInstanciaTmp = new ArrayList<UsuarioInstancia>();
        lstUsuarioInstanciaTmp = getService().findByNamedQuery("UsuarioInstancia.findByNidUsuario", new Object[]{usuario.getId()});
        ControlAcceso control = ((ControlAcceso) getSpringBean(Constante.SESSION_ACCESO));
        
        List<Instancia> target = new ArrayList<Instancia>();
        for (Object NIdInstancia : instancias.getTarget()) {
            if (NIdInstancia instanceof String) {
                if (mapaInstancias.containsKey(NIdInstancia.toString())) {
                    target.add(mapaInstancias.get(NIdInstancia.toString()));
                }
            } else {
                target.add((Instancia) NIdInstancia);
            }
        }
        
        for (UsuarioInstancia usuarioInstancia : lstUsuarioInstanciaTmp) {
            //si no esta, se debe desactivar
            if (existeInstancia(target, usuarioInstancia.getInstancia().getId()) == null) {
                usuarioInstancia.setFlgActivo(Constante.ESTADO_INACTIVO);
                usuarioInstancia.setFlgPrincipal(Constante.ESTADO_INACTIVO);
                usuarioInstancia.setNIdCtrlAccesoWeb(control.getId());
                //getService().save(usuarioInstancia);
                guardarAuditoriaUsuarioInstancia(usuarioInstancia, Constante.TIPO_OPERACION_ELIMINAR);
            }
        }
        
        int i=0;
        UsuarioInstancia usuarioInstancia = null;
        for (Instancia instancia : target) {
            usuarioInstancia = existeUsuarioInstancia(lstUsuarioInstanciaTmp, instancia.getId(), usuario.getId());
            if (usuarioInstancia == null) {
                usuarioInstancia = new UsuarioInstancia();
                usuarioInstancia.setFlgActivo(Constante.ESTADO_ACTIVO);
                usuarioInstancia.setFlgPrincipal(Constante.ESTADO_INACTIVO);
                usuarioInstancia.setInstancia(instancia);
                usuarioInstancia.setUsuario(usuario);
                usuarioInstancia.setNIdCtrlAccesoWeb(control.getId());
                usuarioInstancia.setUsuarioInstanciaPK(new UsuarioInstanciaPK(instancia.getId(), usuario.getId()));
                if(i==0){
                    usuarioInstancia.setFlgPrincipal(Constante.ESTADO_ACTIVO);
                }
                //getService().save(usuarioInstancia);
                guardarAuditoriaUsuarioInstancia(usuarioInstancia, Constante.TIPO_OPERACION_INSERTAR);
            }else{
                usuarioInstancia.setFlgPrincipal(Constante.ESTADO_INACTIVO);
                if (i == 0) {
                    usuarioInstancia.setFlgPrincipal(Constante.ESTADO_ACTIVO);
                }
                if(usuarioInstancia.getFlgActivo().equals(Constante.ESTADO_INACTIVO)){
                    usuarioInstancia.setFlgActivo(Constante.ESTADO_ACTIVO);   
                }
                usuarioInstancia.setNIdCtrlAccesoWeb(control.getId());
                //getService().save(usuarioInstancia);
                guardarAuditoriaUsuarioInstancia(usuarioInstancia, Constante.TIPO_OPERACION_MODIFICAR);
            } 
            i++;
        }
        List<Instancia> source = new ArrayList<Instancia>();
        List<Instancia> sourceTmp = new ArrayList<Instancia>();
        sourceTmp = getService().findByNamedQuery("Instancia.findByFlgActivo", new Object[]{Constante.ESTADO_ACTIVO});
        for (Instancia instanciaTmp : sourceTmp) {
            mapaInstancias.put(instanciaTmp.getId().toString(), instanciaTmp);
            if (existeInstancia(target, instanciaTmp.getId()) == null) {
                source.add(instanciaTmp);
            }
        }
        instancias = new DualListModel<Instancia>(source, target);
        setMessageSuccess("Se actualizaron las instancias del usuario " + "'" + usuario.getNombreCompleto() + "'" + " satisfactoriamente.");
        setBean(bean);
    }
    
    public void guardarAuditoriaUsuarioInstancia(UsuarioInstancia usuarioInstancia, String tipoOperacion){
        try {
            setBean(usuarioInstancia);
            if(tipoOperacion.equals(Constante.TIPO_OPERACION_INSERTAR)){
                super.beforeSave(null);
                super.doSave(null);
                log.info("End of Transaction: 'Save'");
            }else if(tipoOperacion.equals(Constante.TIPO_OPERACION_MODIFICAR)){
                super.beforeUpdate(null);
                super.doUpdate(null);
                log.info("End of Transaction: 'Update'");
            }else{
                super.beforeDelete(null);
                super.doDelete(null);
                log.info("End of Transaction: 'Delete'");
            }
        } catch (Exception e) {
            log.error("ERROR EN guardarAuditoriaUsuarioInstancia:"+e.getMessage());
        }
    }
    
    public UsuarioInstancia existeUsuarioInstancia(List<UsuarioInstancia> lista, Long NIdInstancia, Long NIdUsuario) {
        for (UsuarioInstancia ui : lista) {
            if (ui.getInstancia().getId().equals(NIdInstancia) && ui.getUsuario().getId().equals(NIdUsuario)) {
                return ui;
            }
        }
        return null;
    }

    public PerfilOpcion getSelectedUsuarioOpcion() {
        return selectedUsuarioOpcion;
    }

    public void setSelectedUsuarioOpcion(PerfilOpcion selectedUsuarioOpcion) {
        this.selectedUsuarioOpcion = selectedUsuarioOpcion;
    }

    public Map<String, Opcion> getMapaOpciones() {
        return mapaOpciones;
    }

    public void setMapaOpciones(Map<String, Opcion> mapaOpciones) {
        this.mapaOpciones = mapaOpciones;
    }

    public Map<String, Perfil> getMapaPefiles() {
        return mapaPefiles;
    }

    public void setMapaPefiles(Map<String, Perfil> mapaPefiles) {
        this.mapaPefiles = mapaPefiles;
    }

    public boolean isEsNuevoExterno() {
        return esNuevoExterno;
    }

    public void setEsNuevoExterno(boolean esNuevoExterno) {
        this.esNuevoExterno = esNuevoExterno;
    }

    public boolean isBActivoPerfil() {
        return BActivoPerfil;
    }

    public void setBActivoPerfil(boolean BActivoPerfil) {
        this.BActivoPerfil = BActivoPerfil;
    }

    public boolean isBHorarioPerfil() {
        return BHorarioPerfil;
    }

    public void setBHorarioPerfil(boolean BHorarioPerfil) {
        this.BHorarioPerfil = BHorarioPerfil;
    }

    public boolean isBTipoAcceso() {
        return BTipoAcceso;
    }

    public void setBTipoAcceso(boolean BTipoAcceso) {
        this.BTipoAcceso = BTipoAcceso;
    }

    public boolean isBMuestraObsPerfil() {
        return BMuestraObsPerfil;
    }

    public void setBMuestraObsPerfil(boolean BMuestraObsPerfil) {
        this.BMuestraObsPerfil = BMuestraObsPerfil;
    }

    public UsuarioPerfil getSelectedPersonalizaPerfil() {
        return selectedPersonalizaPerfil;
    }

    public void setSelectedPersonalizaPerfil(UsuarioPerfil selectedPersonalizaPerfil) {
        this.selectedPersonalizaPerfil = selectedPersonalizaPerfil;
    }

    public HorarioPerfil getSelectedHorarioPerfil() {
        return selectedHorarioPerfil;
    }

    public void setSelectedHorarioPerfil(HorarioPerfil selectedHorarioPerfil) {
        this.selectedHorarioPerfil = selectedHorarioPerfil;
    }

    public List<HorarioPerfil> getLstUsuarioHorarioPerfil() {
        return lstUsuarioHorarioPerfil;
    }

    public void setLstUsuarioHorarioPerfil(List<HorarioPerfil> lstUsuarioHorarioPerfil) {
        this.lstUsuarioHorarioPerfil = lstUsuarioHorarioPerfil;
    }

    public boolean isBActivoHorarioPerfil() {
        return BActivoHorarioPerfil;
    }

    public void setBActivoHorarioPerfil(boolean BActivoHorarioPerfil) {
        this.BActivoHorarioPerfil = BActivoHorarioPerfil;
    }

    public boolean isBMuestraObsHorarioPerfil() {
        return BMuestraObsHorarioPerfil;
    }

    public void setBMuestraObsHorarioPerfil(boolean BMuestraObsHorarioPerfil) {
        this.BMuestraObsHorarioPerfil = BMuestraObsHorarioPerfil;
    }

    public Map<String, String> getMapaUnidadTerritorial() {
        return mapaUnidadTerritorial;
    }

    public void setMapaUnidadTerritorial(Map<String, String> mapaUnidadTerritorial) {
        this.mapaUnidadTerritorial = mapaUnidadTerritorial;
    }

    public List<Zonal> getLstComboZonal() {
        return lstComboZonal;
    }

    public void setLstComboZonal(List<Zonal> lstComboZonal) {
        this.lstComboZonal = lstComboZonal;
    }

    public Map<String, String> getMapaTipoUsuario() {
        return mapaTipoUsuario;
    }

    public void setMapaTipoUsuario(Map<String, String> mapaTipoUsuario) {
        this.mapaTipoUsuario = mapaTipoUsuario;
    }

    public List<UnidadOrganizacional> getLstComboUnidadOrganizacional() {
        return lstComboUnidadOrganizacional;
    }

    public void setLstComboUnidadOrganizacional(List<UnidadOrganizacional> lstComboUnidadOrganizacional) {
        this.lstComboUnidadOrganizacional = lstComboUnidadOrganizacional;
    }

    public DualListModel<Instancia> getInstancias() {
        return instancias;
    }

    public void setInstancias(DualListModel<Instancia> instancias) {
        this.instancias = instancias;
    }

    public Map<String, Instancia> getMapaInstancias() {
        return mapaInstancias;
    }

    public void setMapaInstancias(Map<String, Instancia> mapaInstancias) {
        this.mapaInstancias = mapaInstancias;
    }

    public List<UsuarioAutorizacion> getLstUsuarioAutorizacion() {
        return lstUsuarioAutorizacion;
    }

    public void setLstUsuarioAutorizacion(List<UsuarioAutorizacion> lstUsuarioAutorizacion) {
        this.lstUsuarioAutorizacion = lstUsuarioAutorizacion;
    }

    public UsuarioAutorizacion getSelectedUsuarioAutorizacion() {
        return selectedUsuarioAutorizacion;
    }

    public void setSelectedUsuarioAutorizacion(UsuarioAutorizacion selectedUsuarioAutorizacion) {
        this.selectedUsuarioAutorizacion = selectedUsuarioAutorizacion;
    }

    public boolean isBActivoAccion() {
        return BActivoAccion;
    }

    public void setBActivoAccion(boolean BActivoAccion) {
        this.BActivoAccion = BActivoAccion;
    }

    public boolean isBTipoAccesoAccion() {
        return BTipoAccesoAccion;
    }

    public void setBTipoAccesoAccion(boolean BTipoAccesoAccion) {
        this.BTipoAccesoAccion = BTipoAccesoAccion;
    }

    public List<UsuarioAutorizacion> getLstUsuarioAccion() {
        return lstUsuarioAccion;
    }

    public void setLstUsuarioAccion(List<UsuarioAutorizacion> lstUsuarioAccion) {
        this.lstUsuarioAccion = lstUsuarioAccion;
    }

    public UsuarioAutorizacion getSelectedUsuarioAccion() {
        return selectedUsuarioAccion;
    }

    public void setSelectedUsuarioAccion(UsuarioAutorizacion selectedUsuarioAccion) {
        this.selectedUsuarioAccion = selectedUsuarioAccion;
    }
    
    public void onEdit(RowEditEvent event) {
        try {
            UsuarioAutorizacion autoriza= (UsuarioAutorizacion)event.getObject();
            getService().save(autoriza);
        } catch (Exception ex) {
            log.error("ERROR EN onEdit="+ex.getMessage());
        }
    }

    public Long getNIdPerfilSeleccionado() {
        return NIdPerfilSeleccionado;
    }

    public void setNIdPerfilSeleccionado(Long NIdPerfilSeleccionado) {
        this.NIdPerfilSeleccionado = NIdPerfilSeleccionado;
    }

    public TreeNode getOpcionTree() {
        return opcionTree;
    }

    public void setOpcionTree(TreeNode opcionTree) {
        this.opcionTree = opcionTree;
    }

    public TreeNode getSelectedOpcionNode() {
        return selectedOpcionNode;
    }

    public void setSelectedOpcionNode(TreeNode selectedOpcionNode) {
        this.selectedOpcionNode = selectedOpcionNode;
    }

    public PerfilOpcion getSelectedPerfilOpcion() {
        return selectedPerfilOpcion;
    }

    public void setSelectedPerfilOpcion(PerfilOpcion selectedPerfilOpcion) {
        this.selectedPerfilOpcion = selectedPerfilOpcion;
    }

    public List<Opcion> getListaOpcionesAutorizadas() {
        return listaOpcionesAutorizadas;
    }

    public void setListaOpcionesAutorizadas(List<Opcion> listaOpcionesAutorizadas) {
        this.listaOpcionesAutorizadas = listaOpcionesAutorizadas;
    }

    public String getTituloPanelAcciones() {
        return tituloPanelAcciones;
    }

    public void setTituloPanelAcciones(String tituloPanelAcciones) {
        this.tituloPanelAcciones = tituloPanelAcciones;
    }

    public String getTituloPanelOpciones() {
        return tituloPanelOpciones;
    }

    public void setTituloPanelOpciones(String tituloPanelOpciones) {
        this.tituloPanelOpciones = tituloPanelOpciones;
    }
    
    public void visualizaOpciones() throws ServiceException{
        visualizaTree = new DefaultTreeNode("root", null);
        Modulo moduloPadre = null;
        if (selectedUsuarioPerfil.getNidPerfil().getNidModulo().getNidModuloPadre() == null) {
            moduloPadre = selectedUsuarioPerfil.getNidPerfil().getNidModulo();
        } else {
            moduloPadre = getUsuarioService().getModuloPadre(selectedUsuarioPerfil.getNidPerfil().getNidModulo().getId());
        }
        TreeNode treePadre = new DefaultTreeNode(moduloPadre, visualizaTree);
        treePadre.setExpanded(true);
        loadPadreTreeVisualiza(treePadre,moduloPadre);
    }

    public void loadPadreTreeVisualiza(TreeNode treePadre, Modulo moduloPadre) throws ServiceException {
        List<Object[]> lstObject = getService().findByNamedQuery("UsuarioAutorizacion.findByUsuarioPerfilAndModuloFirstLevelNodes", new Object[]{selectedUsuarioPerfil.getId(), Constante.ESTADO_ACTIVO, Constante.ESTADO_ACTIVO, selectedUsuarioPerfil.getNidPerfil().getId(), moduloPadre.getId()});
        List<PerfilOpcion> lstOpcionPadre = new ArrayList<PerfilOpcion>();
        PerfilOpcion po = null;
        for (Object[] obj : lstObject) {
            po = new PerfilOpcion();
            po.setOpcion((Opcion) obj[0]);
            po.setPerfil(selectedUsuarioPerfil.getNidPerfil());
            po.setFlgConsulta(obj[1].toString());
            lstOpcionPadre.add(po);
        }
        for (PerfilOpcion perfilOpcion : lstOpcionPadre) {
            TreeNode padre = new DefaultTreeNode("document", perfilOpcion, treePadre);
            padre.setExpanded(true);
            loadHijoTreeVisualiza(padre, perfilOpcion, selectedUsuarioPerfil, moduloPadre);
        }
        List<Modulo> lstModuloHijos = getService().findByNamedQuery("Modulo.findByNidModuloPadreAndFlgActivo", new Object[]{moduloPadre.getId(), Constante.ESTADO_ACTIVO});
        for (Modulo modulo : lstModuloHijos) {
            TreeNode hijoMo = new DefaultTreeNode(modulo, treePadre);
            hijoMo.setExpanded(true);
            loadPadreTreeVisualiza(hijoMo, modulo);
        }
    }
    
    public void loadHijoTreeVisualiza(TreeNode hijo, PerfilOpcion opHijo, UsuarioPerfil selectedUsuarioPerfil, Modulo moduloHijo) throws ServiceException {
        List<Object[]> lstObject = getService().findByNamedQuery("UsuarioAutorizacion.findByUsuarioPerfilAndModuloOtherLevelNodes", new Object[]{selectedUsuarioPerfil.getId(), Constante.ESTADO_ACTIVO, Constante.ESTADO_ACTIVO, selectedUsuarioPerfil.getNidPerfil().getId(), opHijo.getOpcion().getId(), moduloHijo.getId()});
        List<PerfilOpcion> lstOpcionHijos = new ArrayList<PerfilOpcion>();
        PerfilOpcion po = null;
        for (Object[] obj : lstObject) {
            po = new PerfilOpcion();
            po.setOpcion((Opcion) obj[0]);
            po.setPerfil(selectedUsuarioPerfil.getNidPerfil());
            po.setFlgConsulta(obj[1].toString());
            lstOpcionHijos.add(po);
        }
        for (PerfilOpcion perfilOpcion : lstOpcionHijos) {
            TreeNode nieto = new DefaultTreeNode("document", perfilOpcion, hijo);
            nieto.setExpanded(true);
            loadHijoTreeVisualiza(nieto, perfilOpcion, selectedUsuarioPerfil, moduloHijo);
        }
    }
    
    public TreeNode getVisualizaTree() {
        return visualizaTree;
    }

    public void setVisualizaTree(TreeNode visualizaTree) {
        this.visualizaTree = visualizaTree;
    }
    
}
